1. 12 10月, 2011 2 次提交
  2. 10 8月, 2011 1 次提交
  3. 21 7月, 2011 3 次提交
    • D
      xfs: convert AIL cursors to use struct list_head · af3e4022
      Dave Chinner 提交于
      The list of active AIL cursors uses a roll-your-own linked list with
      special casing for the AIL push cursor. Simplify this code by
      replacing the list with standard struct list_head lists, and use a
      separate list_head to track the active cursors. This allows us to
      treat the AIL push cursor as a generic cursor rather than as a
      special case, further simplifying the code.
      
      Further, fix the duplicate push cursor initialisation that the
      special case handling was hiding, and clean up all the comments
      around the active cursor list handling.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NAlex Elder <aelder@sgi.com>
      af3e4022
    • D
      xfs: remove confusing ail cursor wrapper · 16b59029
      Dave Chinner 提交于
      xfs_trans_ail_cursor_set() doesn't set the cursor to the current log
      item, it sets it to the next item. There is already a function for
      doing this - xfs_trans_ail_cursor_next() - and the _set function is
      simply a two line wrapper.  Remove it and open code the setting of
      the cursor in the two locations that call it to remove the
      confusion.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NAlex Elder <aelder@sgi.com>
      16b59029
    • D
      xfs: use a cursor for bulk AIL insertion · 1d8c95a3
      Dave Chinner 提交于
      Delayed logging can insert tens of thousands of log items into the
      AIL at the same LSN. When the committing of log commit records
      occur, we can get insertions occurring at an LSN that is not at the
      end of the AIL. If there are thousands of items in the AIL on the
      tail LSN, each insertion has to walk the AIL to find the correct
      place to insert the new item into the AIL. This can consume large
      amounts of CPU time and block other operations from occurring while
      the traversals are in progress.
      
      To avoid this repeated walk, use a AIL cursor to record
      where we should be inserting the new items into the AIL without
      having to repeat the walk. The cursor infrastructure already
      provides this functionality for push walks, so is a simple extension
      of existing code. While this will not avoid the initial walk, it
      will avoid repeating it tens of thousands of times during a single
      checkpoint commit.
      
      This version includes logic improvements from Christoph Hellwig.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NAlex Elder <aelder@sgi.com>
      1d8c95a3
  4. 10 5月, 2011 8 次提交
    • D
      xfs: fix race condition in AIL push trigger · 7ac95657
      Dave Chinner 提交于
      The recent conversion of the xfsaild functionality to a work queue
      introduced a hard-to-hit log space grant hang. One is caused by a
      race condition in determining whether there is a psh in progress or
      not.
      
      The XFS_AIL_PUSHING_BIT is used to determine whether a push is
      currently in progress.  When the AIL push work completes, it checked
      whether the target changed and cleared the PUSHING bit to allow a
      new push to be requeued. The race condition is as follows:
      
      	Thread 1		push work
      
      	smp_wmb()
      				smp_rmb()
      				check ailp->xa_target unchanged
      	update ailp->xa_target
      	test/set PUSHING bit
      	does not queue
      				clear PUSHING bit
      				does not requeue
      
      Now that the push target is updated, new attempts to push the AIL
      will not trigger as the push target will be the same, and hence
      despite trying to push the AIL we won't ever wake it again.
      
      The fix is to ensure that the AIL push work clears the PUSHING bit
      before it checks if the target is unchanged.
      
      As a result, both push triggers operate on the same test/set bit
      criteria, so even if we race in the push work and miss the target
      update, the thread requesting the push will still set the PUSHING
      bit and queue the push work to occur. For safety sake, the same
      queue check is done if the push work detects the target change,
      though only one of the two will will queue new work due to the use
      of test_and_set_bit() checks.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NAlex Elder <aelder@sgi.com>
      
      (cherry picked from commit e4d3c4a4)
      7ac95657
    • D
      xfs: make AIL target updates and compares 32bit safe. · fe0da767
      Dave Chinner 提交于
      The recent conversion of the xfsaild functionality to a work queue
      introduced a hard-to-hit log space grant hang. One of the problems
      noticed was that updates of the push target are not 32 bit safe as
      the target is a 64 bit value.
      
      We cannot copy a 64 bit LSN without the possibility of corrupting
      the result when racing with another updating thread. We have
      function to do this update safely without needing to care about
      32/64 bit issues - xfs_trans_ail_copy_lsn() - so use that when
      updating the AIL push target.
      
      Also move the reading of the target in the push work inside the AIL
      lock, and use XFS_LSN_CMP() for the unlocked comparison during work
      termination to close read holes as well.
      Signed-off-by: NDave Chinner <david@fromorbit.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NAlex Elder <aelder@sgi.com>
      
      (cherry picked from commit fd5670f2)
      fe0da767
    • D
      xfs: always push the AIL to the target · 50e86686
      Dave Chinner 提交于
      The recent conversion of the xfsaild functionality to a work queue
      introduced a hard-to-hit log space grant hang. One of the problems
      discovered is a target mismatch between the item pushing loop and
      the target itself.
      
      The push trigger checks for the target increasing (i.e. new target >
      current) while the push loop only pushes items that have a LSN <
      current. As a result, we can get the situation where the push target
      is X, the items at the tail of the AIL have LSN X and they don't get
      pushed. The push work then completes thinking it is done, and cannot
      be restarted until the push target increases to >= X + 1. If the
      push target then never increases (because the tail is not moving),
      then we never run the push work again and we stall.
      
      Fix it by making sure log items with a LSN that matches the target
      exactly are pushed during the loop.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NAlex Elder <aelder@sgi.com>
      
      (cherry picked from commit cb64026b)
      50e86686
    • D
      xfs: exit AIL push work correctly when AIL is empty · 9e7004e7
      Dave Chinner 提交于
      The recent conversion of the xfsaild functionality to a work queue
      introduced a hard-to-hit log space grant hang. The main cause is a
      regression where a work exit path fails to clear the PUSHING state
      and recheck the target correctly.
      
      Make both exit paths do the same PUSHING bit clearing and target
      checking when the "no more work to be done" condition is hit.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NAlex Elder <aelder@sgi.com>
      
      (cherry picked from commit ea35a200)
      9e7004e7
    • D
      xfs: fix race condition in AIL push trigger · e4d3c4a4
      Dave Chinner 提交于
      The recent conversion of the xfsaild functionality to a work queue
      introduced a hard-to-hit log space grant hang. One is caused by a
      race condition in determining whether there is a psh in progress or
      not.
      
      The XFS_AIL_PUSHING_BIT is used to determine whether a push is
      currently in progress.  When the AIL push work completes, it checked
      whether the target changed and cleared the PUSHING bit to allow a
      new push to be requeued. The race condition is as follows:
      
      	Thread 1		push work
      
      	smp_wmb()
      				smp_rmb()
      				check ailp->xa_target unchanged
      	update ailp->xa_target
      	test/set PUSHING bit
      	does not queue
      				clear PUSHING bit
      				does not requeue
      
      Now that the push target is updated, new attempts to push the AIL
      will not trigger as the push target will be the same, and hence
      despite trying to push the AIL we won't ever wake it again.
      
      The fix is to ensure that the AIL push work clears the PUSHING bit
      before it checks if the target is unchanged.
      
      As a result, both push triggers operate on the same test/set bit
      criteria, so even if we race in the push work and miss the target
      update, the thread requesting the push will still set the PUSHING
      bit and queue the push work to occur. For safety sake, the same
      queue check is done if the push work detects the target change,
      though only one of the two will will queue new work due to the use
      of test_and_set_bit() checks.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NAlex Elder <aelder@sgi.com>
      e4d3c4a4
    • D
      xfs: make AIL target updates and compares 32bit safe. · fd5670f2
      Dave Chinner 提交于
      The recent conversion of the xfsaild functionality to a work queue
      introduced a hard-to-hit log space grant hang. One of the problems
      noticed was that updates of the push target are not 32 bit safe as
      the target is a 64 bit value.
      
      We cannot copy a 64 bit LSN without the possibility of corrupting
      the result when racing with another updating thread. We have
      function to do this update safely without needing to care about
      32/64 bit issues - xfs_trans_ail_copy_lsn() - so use that when
      updating the AIL push target.
      
      Also move the reading of the target in the push work inside the AIL
      lock, and use XFS_LSN_CMP() for the unlocked comparison during work
      termination to close read holes as well.
      Signed-off-by: NDave Chinner <david@fromorbit.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NAlex Elder <aelder@sgi.com>
      fd5670f2
    • D
      xfs: always push the AIL to the target · cb64026b
      Dave Chinner 提交于
      The recent conversion of the xfsaild functionality to a work queue
      introduced a hard-to-hit log space grant hang. One of the problems
      discovered is a target mismatch between the item pushing loop and
      the target itself.
      
      The push trigger checks for the target increasing (i.e. new target >
      current) while the push loop only pushes items that have a LSN <
      current. As a result, we can get the situation where the push target
      is X, the items at the tail of the AIL have LSN X and they don't get
      pushed. The push work then completes thinking it is done, and cannot
      be restarted until the push target increases to >= X + 1. If the
      push target then never increases (because the tail is not moving),
      then we never run the push work again and we stall.
      
      Fix it by making sure log items with a LSN that matches the target
      exactly are pushed during the loop.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NAlex Elder <aelder@sgi.com>
      cb64026b
    • D
      xfs: exit AIL push work correctly when AIL is empty · ea35a200
      Dave Chinner 提交于
      The recent conversion of the xfsaild functionality to a work queue
      introduced a hard-to-hit log space grant hang. The main cause is a
      regression where a work exit path fails to clear the PUSHING state
      and recheck the target correctly.
      
      Make both exit paths do the same PUSHING bit clearing and target
      checking when the "no more work to be done" condition is hit.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NAlex Elder <aelder@sgi.com>
      ea35a200
  5. 08 4月, 2011 3 次提交
    • D
      xfs: push the AIL from memory reclaim and periodic sync · fd074841
      Dave Chinner 提交于
      When we are short on memory, we want to expedite the cleaning of
      dirty objects.  Hence when we run short on memory, we need to kick
      the AIL flushing into action to clean as many dirty objects as
      quickly as possible.  To implement this, sample the lsn of the log
      item at the head of the AIL and use that as the push target for the
      AIL flush.
      
      Further, we keep items in the AIL that are dirty that are not
      tracked any other way, so we can get objects sitting in the AIL that
      don't get written back until the AIL is pushed. Hence to get the
      filesystem to the idle state, we might need to push the AIL to flush
      out any remaining dirty objects sitting in the AIL. This requires
      the same push mechanism as the reclaim push.
      
      This patch also renames xfs_trans_ail_tail() to xfs_ail_min_lsn() to
      match the new xfs_ail_max_lsn() function introduced in this patch.
      Similarly for xfs_trans_ail_push -> xfs_ail_push.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NAlex Elder <aelder@sgi.com>
      fd074841
    • D
      xfs: clean up code layout in xfs_trans_ail.c · cd4a3c50
      Dave Chinner 提交于
      This patch rearranges the location of functions in xfs_trans_ail.c
      to remove the need for forward declarations of those functions in
      preparation for adding new functions without the need for forward
      declarations.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NAlex Elder <aelder@sgi.com>
      cd4a3c50
    • D
      xfs: convert the xfsaild threads to a workqueue · 0bf6a5bd
      Dave Chinner 提交于
      Similar to the xfssyncd, the per-filesystem xfsaild threads can be
      converted to a global workqueue and run periodically by delayed
      works. This makes sense for the AIL pushing because it uses
      variable timeouts depending on the work that needs to be done.
      
      By removing the xfsaild, we simplify the AIL pushing code and
      remove the need to spread the code to implement the threading
      and pushing across multiple files.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NAlex Elder <aelder@sgi.com>
      0bf6a5bd
  6. 07 3月, 2011 1 次提交
  7. 20 12月, 2010 4 次提交
    • D
      xfs: use AIL bulk delete function to implement single delete · 9552e7f2
      Dave Chinner 提交于
      We now have two copies of AIL delete operations that are mostly
      duplicate functionality. The single log item deletes can be
      implemented via the bulk updates by turning xfs_trans_ail_delete()
      into a simple wrapper. This removes all the duplicate delete
      functionality and associated helpers.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      9552e7f2
    • D
      xfs: use AIL bulk update function to implement single updates · e6059949
      Dave Chinner 提交于
      We now have two copies of AIL insert operations that are mostly
      duplicate functionality. The single log item updates can be
      implemented via the bulk updates by turning xfs_trans_ail_update()
      into a simple wrapper. This removes all the duplicate insert
      functionality and associated helpers.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      e6059949
    • D
      xfs: remove all the inodes on a buffer from the AIL in bulk · 30136832
      Dave Chinner 提交于
      When inode buffer IO completes, usually all of the inodes are removed from the
      AIL. This involves processing them one at a time and taking the AIL lock once
      for every inode. When all CPUs are processing inode IO completions, this causes
      excessive amount sof contention on the AIL lock.
      
      Instead, change the way we process inode IO completion in the buffer
      IO done callback. Allow the inode IO done callback to walk the list
      of IO done callbacks and pull all the inodes off the buffer in one
      go and then process them as a batch.
      
      Once all the inodes for removal are collected, take the AIL lock
      once and do a bulk removal operation to minimise traffic on the AIL
      lock.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      30136832
    • D
      xfs: bulk AIL insertion during transaction commit · 0e57f6a3
      Dave Chinner 提交于
      When inserting items into the AIL from the transaction committed
      callbacks, we take the AIL lock for every single item that is to be
      inserted. For a CIL checkpoint commit, this can be tens of thousands
      of individual inserts, yet almost all of the items will be inserted
      at the same point in the AIL because they have the same index.
      
      To reduce the overhead and contention on the AIL lock for such
      operations, introduce a "bulk insert" operation which allows a list
      of log items with the same LSN to be inserted in a single operation
      via a list splice. To do this, we need to pre-sort the log items
      being committed into a temporary list for insertion.
      
      The complexity is that not every log item will end up with the same
      LSN, and not every item is actually inserted into the AIL. Items
      that don't match the commit LSN will be inserted and unpinned as per
      the current one-at-a-time method (relatively rare), while items that
      are not to be inserted will be unpinned and freed immediately. Items
      that are to be inserted at the given commit lsn are placed in a
      temporary array and inserted into the AIL in bulk each time the
      array fills up.
      
      As a result of this, we trade off AIL hold time for a significant
      reduction in traffic. lock_stat output shows that the worst case
      hold time is unchanged, but contention from AIL inserts drops by an
      order of magnitude and the number of lock traversal decreases
      significantly.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      0e57f6a3
  8. 03 12月, 2010 1 次提交
    • D
      xfs: clean up xfs_ail_delete() · eb3efa12
      Dave Chinner 提交于
      xfs_ail_delete() has a needlessly complex interface. It returns the log item
      that was passed in for deletion (which the callers then assert is identical to
      the one passed in), and callers of xfs_ail_delete() still need to invalidate
      current traversal cursors.
      
      Make xfs_ail_delete() return void, move the cursor invalidation inside it, and
      clean up the callers just to use the log item pointer they passed in.
      
      While cleaning up, remove the messy and unnecessary "/* ARGUSED */" comments
      around all these functions.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      eb3efa12
  9. 27 7月, 2010 1 次提交
    • C
      xfs: drop dmapi hooks · 288699fe
      Christoph Hellwig 提交于
      Dmapi support was never merged upstream, but we still have a lot of hooks
      bloating XFS for it, all over the fast pathes of the filesystem.
      
      This patch drops over 700 lines of dmapi overhead.  If we'll ever get HSM
      support in mainline at least the namespace events can be done much saner
      in the VFS instead of the individual filesystem, so it's not like this
      is much help for future work.
      Signed-off-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NDave Chinner <dchinner@redhat.com>
      288699fe
  10. 02 2月, 2010 1 次提交
    • D
      xfs: Don't issue buffer IO direct from AIL push V2 · d808f617
      Dave Chinner 提交于
      All buffers logged into the AIL are marked as delayed write.
      When the AIL needs to push the buffer out, it issues an async write of the
      buffer. This means that IO patterns are dependent on the order of
      buffers in the AIL.
      
      Instead of flushing the buffer, promote the buffer in the delayed
      write list so that the next time the xfsbufd is run the buffer will
      be flushed by the xfsbufd. Return the state to the xfsaild that the
      buffer was promoted so that the xfsaild knows that it needs to cause
      the xfsbufd to run to flush the buffers that were promoted.
      
      Using the xfsbufd for issuing the IO allows us to dispatch all
      buffer IO from the one queue. This means that we can make much more
      enlightened decisions on what order to flush buffers to disk as
      we don't have multiple places issuing IO. Optimisations to xfsbufd
      will be in a future patch.
      
      Version 2
      - kill XFS_ITEM_FLUSHING as it is now unused.
      Signed-off-by: NDave Chinner <david@fromorbit.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      d808f617
  11. 22 1月, 2010 1 次提交
    • C
      xfs: cleanup up xfs_log_force calling conventions · a14a348b
      Christoph Hellwig 提交于
      Remove the XFS_LOG_FORCE argument which was always set, and the
      XFS_LOG_URGE define, which was never used.
      
      Split xfs_log_force into a two helpers - xfs_log_force which forces
      the whole log, and xfs_log_force_lsn which forces up to the
      specified LSN.  The underlying implementations already were entirely
      separate, as were the users.
      
      Also re-indent the new _xfs_log_force/_xfs_log_force which
      previously had a weird coding style.
      Signed-off-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NAlex Elder <aelder@sgi.com>
      a14a348b
  12. 16 1月, 2010 1 次提交
  13. 18 11月, 2009 1 次提交
    • N
      xfs: copy li_lsn before dropping AIL lock · 6c06f072
      Nathaniel W. Turner 提交于
      Access to log items on the AIL is generally protected by m_ail_lock;
      this is particularly needed when we're getting or setting the 64-bit
      li_lsn on a 32-bit platform.  This patch fixes a couple places where we
      were accessing the log item after dropping the AIL lock on 32-bit
      machines.
      
      This can result in a partially-zeroed log->l_tail_lsn if
      xfs_trans_ail_delete is racing with xfs_trans_ail_update, and in at
      least some cases, this can leave the l_tail_lsn with a zero cycle
      number, which means xlog_space_left will think the log is full (unless
      CONFIG_XFS_DEBUG is set, in which case we'll trip an ASSERT), leading to
      processes stuck forever in xlog_grant_log_space.
      
      Thanks to Adrian VanderSpek for first spotting the race potential and to
      Dave Chinner for debug assistance.
      Signed-off-by: NNathaniel W. Turner <nate@houseofnate.net>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NAlex Elder <aelder@sgi.com>
      6c06f072
  14. 29 3月, 2009 1 次提交
  15. 30 10月, 2008 6 次提交
    • D
      [XFS] correctly select first log item to push · 7ee49acf
      David Chinner 提交于
      Under heavy metadata load we are seeing log hangs. The AIL has items in it
      ready to be pushed, and they are within the push target window. However,
      we are not pushing them when the last pushed LSN is less than the LSN of
      the first log item on the AIL. This is a regression introduced by the AIL
      push cursor modifications.
      
      SGI-PV: 987246
      
      SGI-Modid: xfs-linux-melb:xfs-kern:32409a
      Signed-off-by: NDavid Chinner <david@fromorbit.com>
      Signed-off-by: NLachlan McIlroy <lachlan@sgi.com>
      Signed-off-by: NTim Shimmin <tes@sgi.com>
      7ee49acf
    • D
      [XFS] Finish removing the mount pointer from the AIL API · 783a2f65
      David Chinner 提交于
      Change all the remaining AIL API functions that are passed struct
      xfs_mount pointers to pass pointers directly to the struct xfs_ail being
      used. With this conversion, all external access to the AIL is via the
      struct xfs_ail. Hence the operation and referencing of the AIL is almost
      entirely independent of the xfs_mount that is using it - it is now much
      more tightly tied to the log and the items it is tracking in the log than
      it is tied to the xfs_mount.
      
      SGI-PV: 988143
      
      SGI-Modid: xfs-linux-melb:xfs-kern:32353a
      Signed-off-by: NDavid Chinner <david@fromorbit.com>
      Signed-off-by: NLachlan McIlroy <lachlan@sgi.com>
      Signed-off-by: NChristoph Hellwig <hch@infradead.org>
      783a2f65
    • D
      [XFS] Move the AIL lock into the struct xfs_ail · c7e8f268
      David Chinner 提交于
      Bring the ail lock inside the struct xfs_ail. This means the AIL can be
      entirely manipulated via the struct xfs_ail rather than needing both the
      struct xfs_mount and the struct xfs_ail.
      
      SGI-PV: 988143
      
      SGI-Modid: xfs-linux-melb:xfs-kern:32350a
      Signed-off-by: NDavid Chinner <david@fromorbit.com>
      Signed-off-by: NLachlan McIlroy <lachlan@sgi.com>
      Signed-off-by: NChristoph Hellwig <hch@infradead.org>
      c7e8f268
    • D
      [XFS] move the AIl traversal over to a consistent interface · 5b00f14f
      David Chinner 提交于
      With the new cursor interface, it makes sense to make all the traversing
      code use the cursor interface and make the old one go away. This means
      more of the AIL interfacing is done by passing struct xfs_ail pointers
      around the place instead of struct xfs_mount pointers.
      
      We can replace the use of xfs_trans_first_ail() in xfs_log_need_covered()
      as it is only checking if the AIL is empty. We can do that with a call to
      xfs_trans_ail_tail() instead, where a zero LSN returned indicates and
      empty AIL...
      
      SGI-PV: 988143
      
      SGI-Modid: xfs-linux-melb:xfs-kern:32348a
      Signed-off-by: NDavid Chinner <david@fromorbit.com>
      Signed-off-by: NLachlan McIlroy <lachlan@sgi.com>
      Signed-off-by: NChristoph Hellwig <hch@infradead.org>
      5b00f14f
    • D
      [XFS] Use a cursor for AIL traversal. · 27d8d5fe
      David Chinner 提交于
      To replace the current generation number ensuring sanity of the AIL
      traversal, replace it with an external cursor that is linked to the AIL.
      
      Basically, we store the next item in the cursor whenever we want to drop
      the AIL lock to do something to the current item. When we regain the lock.
      the current item may already be free, so we can't reference it, but the
      next item in the traversal is already held in the cursor.
      
      When we move or delete an object, we search all the active cursors and if
      there is an item match we clear the cursor(s) that point to the object.
      This forces the traversal to restart transparently.
      
      We don't invalidate the cursor on insert because the cursor still points
      to a valid item. If the intem is inserted between the current item and the
      cursor it does not matter; the traversal is considered to be past the
      insertion point so it will be picked up in the next traversal.
      
      Hence traversal restarts pretty much disappear altogether with this method
      of traversal, which should substantially reduce the overhead of pushing on
      a busy AIL.
      
      Version 2 o add restart logic o comment cursor interface o minor cleanups
      
      SGI-PV: 988143
      
      SGI-Modid: xfs-linux-melb:xfs-kern:32347a
      Signed-off-by: NDavid Chinner <david@fromorbit.com>
      Signed-off-by: NLachlan McIlroy <lachlan@sgi.com>
      Signed-off-by: NChristoph Hellwig <hch@infradead.org>
      27d8d5fe
    • D
      [XFS] Allocate the struct xfs_ail · 82fa9012
      David Chinner 提交于
      Rather than embedding the struct xfs_ail in the struct xfs_mount, allocate
      it during AIL initialisation. Add a back pointer to the struct xfs_ail so
      that we can pass around the xfs_ail and still be able to access the
      xfs_mount if need be. This is th first step involved in isolating the AIL
      implementation from the surrounding filesystem code.
      
      SGI-PV: 988143
      
      SGI-Modid: xfs-linux-melb:xfs-kern:32346a
      Signed-off-by: NDavid Chinner <david@fromorbit.com>
      Signed-off-by: NLachlan McIlroy <lachlan@sgi.com>
      Signed-off-by: NChristoph Hellwig <hch@infradead.org>
      82fa9012
  16. 18 4月, 2008 2 次提交
  17. 06 3月, 2008 1 次提交
  18. 07 2月, 2008 2 次提交
    • D
      [XFS] Make xfs_ail_check check less by default · de08dbc1
      David Chinner 提交于
      Checking the entire AIL on every insert and remove is prohibitively
      expensive - the sustained sequntial create rate on a single disk drops
      from about 1800/s to 60/s because of this checking resulting in the
      xfslogd becoming cpu bound.
      
      By default on debug builds, only check the next and previous entries in
      the list to ensure they are ordered correctly. If you really want, define
      XFS_TRANS_DEBUG to use the old behaviour.
      
      SGI-PV: 972759
      SGI-Modid: xfs-linux-melb:xfs-kern:30372a
      Signed-off-by: NDavid Chinner <dgc@sgi.com>
      Signed-off-by: NLachlan McIlroy <lachlan@sgi.com>
      de08dbc1
    • D
      [XFS] Move AIL pushing into it's own thread · 249a8c11
      David Chinner 提交于
      When many hundreds to thousands of threads all try to do simultaneous
      transactions and the log is in a tail-pushing situation (i.e. full), we
      can get multiple threads walking the AIL list and contending on the AIL
      lock.
      
      The AIL push is, in effect, a simple I/O dispatch algorithm complicated by
      the ordering constraints placed on it by the transaction subsystem. It
      really does not need multiple threads to push on it - even when only a
      single CPU is pushing the AIL, it can push the I/O out far faster that
      pretty much any disk subsystem can handle.
      
      So, to avoid contention problems stemming from multiple list walkers, move
      the list walk off into another thread and simply provide a "target" to
      push to. When a thread requires a push, it sets the target and wakes the
      push thread, then goes to sleep waiting for the required amount of space
      to become available in the log.
      
      This mechanism should also be a lot fairer under heavy load as the waiters
      will queue in arrival order, rather than queuing in "who completed a push
      first" order.
      
      Also, by moving the pushing to a separate thread we can do more
      effectively overload detection and prevention as we can keep context from
      loop iteration to loop iteration. That is, we can push only part of the
      list each loop and not have to loop back to the start of the list every
      time we run. This should also help by reducing the number of items we try
      to lock and/or push items that we cannot move.
      
      Note that this patch is not intended to solve the inefficiencies in the
      AIL structure and the associated issues with extremely large list
      contents. That needs to be addresses separately; parallel access would
      cause problems to any new structure as well, so I'm only aiming to isolate
      the structure from unbounded parallelism here.
      
      SGI-PV: 972759
      SGI-Modid: xfs-linux-melb:xfs-kern:30371a
      Signed-off-by: NDavid Chinner <dgc@sgi.com>
      Signed-off-by: NLachlan McIlroy <lachlan@sgi.com>
      249a8c11