|
@@ -372,12 +372,24 @@ xfs_ail_worker(
|
|
|
xfs_lsn_t lsn;
|
|
|
xfs_lsn_t target;
|
|
|
long tout = 10;
|
|
|
- int flush_log = 0;
|
|
|
int stuck = 0;
|
|
|
int count = 0;
|
|
|
int push_xfsbufd = 0;
|
|
|
|
|
|
+ /*
|
|
|
+ * If last time we ran we encountered pinned items, force the log first
|
|
|
+ * and wait for it before pushing again.
|
|
|
+ */
|
|
|
spin_lock(&ailp->xa_lock);
|
|
|
+ if (ailp->xa_last_pushed_lsn == 0 && ailp->xa_log_flush &&
|
|
|
+ !list_empty(&ailp->xa_ail)) {
|
|
|
+ ailp->xa_log_flush = 0;
|
|
|
+ spin_unlock(&ailp->xa_lock);
|
|
|
+ XFS_STATS_INC(xs_push_ail_flush);
|
|
|
+ xfs_log_force(mp, XFS_LOG_SYNC);
|
|
|
+ spin_lock(&ailp->xa_lock);
|
|
|
+ }
|
|
|
+
|
|
|
target = ailp->xa_target;
|
|
|
lip = xfs_trans_ail_cursor_first(ailp, &cur, ailp->xa_last_pushed_lsn);
|
|
|
if (!lip || XFS_FORCED_SHUTDOWN(mp)) {
|
|
@@ -435,7 +447,7 @@ xfs_ail_worker(
|
|
|
case XFS_ITEM_PINNED:
|
|
|
XFS_STATS_INC(xs_push_ail_pinned);
|
|
|
stuck++;
|
|
|
- flush_log = 1;
|
|
|
+ ailp->xa_log_flush++;
|
|
|
break;
|
|
|
|
|
|
case XFS_ITEM_LOCKED:
|
|
@@ -480,16 +492,6 @@ xfs_ail_worker(
|
|
|
xfs_trans_ail_cursor_done(ailp, &cur);
|
|
|
spin_unlock(&ailp->xa_lock);
|
|
|
|
|
|
- if (flush_log) {
|
|
|
- /*
|
|
|
- * If something we need to push out was pinned, then
|
|
|
- * push out the log so it will become unpinned and
|
|
|
- * move forward in the AIL.
|
|
|
- */
|
|
|
- XFS_STATS_INC(xs_push_ail_flush);
|
|
|
- xfs_log_force(mp, 0);
|
|
|
- }
|
|
|
-
|
|
|
if (push_xfsbufd) {
|
|
|
/* we've got delayed write buffers to flush */
|
|
|
wake_up_process(mp->m_ddev_targp->bt_task);
|
|
@@ -500,6 +502,7 @@ out_done:
|
|
|
if (!count) {
|
|
|
/* We're past our target or empty, so idle */
|
|
|
ailp->xa_last_pushed_lsn = 0;
|
|
|
+ ailp->xa_log_flush = 0;
|
|
|
|
|
|
/*
|
|
|
* We clear the XFS_AIL_PUSHING_BIT first before checking
|
|
@@ -532,9 +535,13 @@ out_done:
|
|
|
* were stuck.
|
|
|
*
|
|
|
* Backoff a bit more to allow some I/O to complete before
|
|
|
- * continuing from where we were.
|
|
|
+ * restarting from the start of the AIL. This prevents us
|
|
|
+ * from spinning on the same items, and if they are pinned will
|
|
|
+ * all the restart to issue a log force to unpin the stuck
|
|
|
+ * items.
|
|
|
*/
|
|
|
tout = 20;
|
|
|
+ ailp->xa_last_pushed_lsn = 0;
|
|
|
}
|
|
|
|
|
|
/* There is more to do, requeue us. */
|