Skip to content

Commit 4800829

Browse files
committed
Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
* 'for-linus' of git://oss.sgi.com/xfs/xfs: xfs: revert to using a kthread for AIL pushing xfs: force the log if we encounter pinned buffers in .iop_pushbuf xfs: do not update xa_last_pushed_lsn for locked items
2 parents 95bc156 + 0030807 commit 4800829

File tree

8 files changed

+69
-62
lines changed

8 files changed

+69
-62
lines changed

fs/xfs/xfs_buf_item.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ xfs_buf_item_push(
629629
* the xfsbufd to get this buffer written. We have to unlock the buffer
630630
* to allow the xfsbufd to write it, too.
631631
*/
632-
STATIC void
632+
STATIC bool
633633
xfs_buf_item_pushbuf(
634634
struct xfs_log_item *lip)
635635
{
@@ -643,6 +643,7 @@ xfs_buf_item_pushbuf(
643643

644644
xfs_buf_delwri_promote(bp);
645645
xfs_buf_relse(bp);
646+
return true;
646647
}
647648

648649
STATIC void

fs/xfs/xfs_dquot_item.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,14 @@ xfs_qm_dqunpin_wait(
183183
* search the buffer cache can be a time consuming thing, and AIL lock is a
184184
* spinlock.
185185
*/
186-
STATIC void
186+
STATIC bool
187187
xfs_qm_dquot_logitem_pushbuf(
188188
struct xfs_log_item *lip)
189189
{
190190
struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip);
191191
struct xfs_dquot *dqp = qlip->qli_dquot;
192192
struct xfs_buf *bp;
193+
bool ret = true;
193194

194195
ASSERT(XFS_DQ_IS_LOCKED(dqp));
195196

@@ -201,17 +202,20 @@ xfs_qm_dquot_logitem_pushbuf(
201202
if (completion_done(&dqp->q_flush) ||
202203
!(lip->li_flags & XFS_LI_IN_AIL)) {
203204
xfs_dqunlock(dqp);
204-
return;
205+
return true;
205206
}
206207

207208
bp = xfs_incore(dqp->q_mount->m_ddev_targp, qlip->qli_format.qlf_blkno,
208209
dqp->q_mount->m_quotainfo->qi_dqchunklen, XBF_TRYLOCK);
209210
xfs_dqunlock(dqp);
210211
if (!bp)
211-
return;
212+
return true;
212213
if (XFS_BUF_ISDELAYWRITE(bp))
213214
xfs_buf_delwri_promote(bp);
215+
if (xfs_buf_ispinned(bp))
216+
ret = false;
214217
xfs_buf_relse(bp);
218+
return ret;
215219
}
216220

217221
/*

fs/xfs/xfs_inode_item.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -708,13 +708,14 @@ xfs_inode_item_committed(
708708
* marked delayed write. If that's the case, we'll promote it and that will
709709
* allow the caller to write the buffer by triggering the xfsbufd to run.
710710
*/
711-
STATIC void
711+
STATIC bool
712712
xfs_inode_item_pushbuf(
713713
struct xfs_log_item *lip)
714714
{
715715
struct xfs_inode_log_item *iip = INODE_ITEM(lip);
716716
struct xfs_inode *ip = iip->ili_inode;
717717
struct xfs_buf *bp;
718+
bool ret = true;
718719

719720
ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED));
720721

@@ -725,18 +726,21 @@ xfs_inode_item_pushbuf(
725726
if (completion_done(&ip->i_flush) ||
726727
!(lip->li_flags & XFS_LI_IN_AIL)) {
727728
xfs_iunlock(ip, XFS_ILOCK_SHARED);
728-
return;
729+
return true;
729730
}
730731

731732
bp = xfs_incore(ip->i_mount->m_ddev_targp, iip->ili_format.ilf_blkno,
732733
iip->ili_format.ilf_len, XBF_TRYLOCK);
733734

734735
xfs_iunlock(ip, XFS_ILOCK_SHARED);
735736
if (!bp)
736-
return;
737+
return true;
737738
if (XFS_BUF_ISDELAYWRITE(bp))
738739
xfs_buf_delwri_promote(bp);
740+
if (xfs_buf_ispinned(bp))
741+
ret = false;
739742
xfs_buf_relse(bp);
743+
return ret;
740744
}
741745

742746
/*

fs/xfs/xfs_linux.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@
6868
#include <linux/ctype.h>
6969
#include <linux/writeback.h>
7070
#include <linux/capability.h>
71+
#include <linux/kthread.h>
72+
#include <linux/freezer.h>
7173
#include <linux/list_sort.h>
7274

7375
#include <asm/page.h>

fs/xfs/xfs_super.c

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1652,24 +1652,13 @@ xfs_init_workqueues(void)
16521652
*/
16531653
xfs_syncd_wq = alloc_workqueue("xfssyncd", WQ_CPU_INTENSIVE, 8);
16541654
if (!xfs_syncd_wq)
1655-
goto out;
1656-
1657-
xfs_ail_wq = alloc_workqueue("xfsail", WQ_CPU_INTENSIVE, 8);
1658-
if (!xfs_ail_wq)
1659-
goto out_destroy_syncd;
1660-
1655+
return -ENOMEM;
16611656
return 0;
1662-
1663-
out_destroy_syncd:
1664-
destroy_workqueue(xfs_syncd_wq);
1665-
out:
1666-
return -ENOMEM;
16671657
}
16681658

16691659
STATIC void
16701660
xfs_destroy_workqueues(void)
16711661
{
1672-
destroy_workqueue(xfs_ail_wq);
16731662
destroy_workqueue(xfs_syncd_wq);
16741663
}
16751664

fs/xfs/xfs_trans.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ typedef struct xfs_item_ops {
350350
void (*iop_unlock)(xfs_log_item_t *);
351351
xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t);
352352
void (*iop_push)(xfs_log_item_t *);
353-
void (*iop_pushbuf)(xfs_log_item_t *);
353+
bool (*iop_pushbuf)(xfs_log_item_t *);
354354
void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t);
355355
} xfs_item_ops_t;
356356

fs/xfs/xfs_trans_ail.c

Lines changed: 48 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
#include "xfs_trans_priv.h"
2929
#include "xfs_error.h"
3030

31-
struct workqueue_struct *xfs_ail_wq; /* AIL workqueue */
32-
3331
#ifdef DEBUG
3432
/*
3533
* Check that the list is sorted as it should be.
@@ -356,16 +354,10 @@ xfs_ail_delete(
356354
xfs_trans_ail_cursor_clear(ailp, lip);
357355
}
358356

359-
/*
360-
* xfs_ail_worker does the work of pushing on the AIL. It will requeue itself
361-
* to run at a later time if there is more work to do to complete the push.
362-
*/
363-
STATIC void
364-
xfs_ail_worker(
365-
struct work_struct *work)
357+
static long
358+
xfsaild_push(
359+
struct xfs_ail *ailp)
366360
{
367-
struct xfs_ail *ailp = container_of(to_delayed_work(work),
368-
struct xfs_ail, xa_work);
369361
xfs_mount_t *mp = ailp->xa_mount;
370362
struct xfs_ail_cursor cur;
371363
xfs_log_item_t *lip;
@@ -427,8 +419,13 @@ xfs_ail_worker(
427419

428420
case XFS_ITEM_PUSHBUF:
429421
XFS_STATS_INC(xs_push_ail_pushbuf);
430-
IOP_PUSHBUF(lip);
431-
ailp->xa_last_pushed_lsn = lsn;
422+
423+
if (!IOP_PUSHBUF(lip)) {
424+
stuck++;
425+
flush_log = 1;
426+
} else {
427+
ailp->xa_last_pushed_lsn = lsn;
428+
}
432429
push_xfsbufd = 1;
433430
break;
434431

@@ -440,7 +437,6 @@ xfs_ail_worker(
440437

441438
case XFS_ITEM_LOCKED:
442439
XFS_STATS_INC(xs_push_ail_locked);
443-
ailp->xa_last_pushed_lsn = lsn;
444440
stuck++;
445441
break;
446442

@@ -501,20 +497,6 @@ xfs_ail_worker(
501497
/* We're past our target or empty, so idle */
502498
ailp->xa_last_pushed_lsn = 0;
503499

504-
/*
505-
* We clear the XFS_AIL_PUSHING_BIT first before checking
506-
* whether the target has changed. If the target has changed,
507-
* this pushes the requeue race directly onto the result of the
508-
* atomic test/set bit, so we are guaranteed that either the
509-
* the pusher that changed the target or ourselves will requeue
510-
* the work (but not both).
511-
*/
512-
clear_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags);
513-
smp_rmb();
514-
if (XFS_LSN_CMP(ailp->xa_target, target) == 0 ||
515-
test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags))
516-
return;
517-
518500
tout = 50;
519501
} else if (XFS_LSN_CMP(lsn, target) >= 0) {
520502
/*
@@ -537,9 +519,30 @@ xfs_ail_worker(
537519
tout = 20;
538520
}
539521

540-
/* There is more to do, requeue us. */
541-
queue_delayed_work(xfs_syncd_wq, &ailp->xa_work,
542-
msecs_to_jiffies(tout));
522+
return tout;
523+
}
524+
525+
static int
526+
xfsaild(
527+
void *data)
528+
{
529+
struct xfs_ail *ailp = data;
530+
long tout = 0; /* milliseconds */
531+
532+
while (!kthread_should_stop()) {
533+
if (tout && tout <= 20)
534+
__set_current_state(TASK_KILLABLE);
535+
else
536+
__set_current_state(TASK_INTERRUPTIBLE);
537+
schedule_timeout(tout ?
538+
msecs_to_jiffies(tout) : MAX_SCHEDULE_TIMEOUT);
539+
540+
try_to_freeze();
541+
542+
tout = xfsaild_push(ailp);
543+
}
544+
545+
return 0;
543546
}
544547

545548
/*
@@ -574,8 +577,9 @@ xfs_ail_push(
574577
*/
575578
smp_wmb();
576579
xfs_trans_ail_copy_lsn(ailp, &ailp->xa_target, &threshold_lsn);
577-
if (!test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags))
578-
queue_delayed_work(xfs_syncd_wq, &ailp->xa_work, 0);
580+
smp_wmb();
581+
582+
wake_up_process(ailp->xa_task);
579583
}
580584

581585
/*
@@ -813,9 +817,18 @@ xfs_trans_ail_init(
813817
INIT_LIST_HEAD(&ailp->xa_ail);
814818
INIT_LIST_HEAD(&ailp->xa_cursors);
815819
spin_lock_init(&ailp->xa_lock);
816-
INIT_DELAYED_WORK(&ailp->xa_work, xfs_ail_worker);
820+
821+
ailp->xa_task = kthread_run(xfsaild, ailp, "xfsaild/%s",
822+
ailp->xa_mount->m_fsname);
823+
if (IS_ERR(ailp->xa_task))
824+
goto out_free_ailp;
825+
817826
mp->m_ail = ailp;
818827
return 0;
828+
829+
out_free_ailp:
830+
kmem_free(ailp);
831+
return ENOMEM;
819832
}
820833

821834
void
@@ -824,6 +837,6 @@ xfs_trans_ail_destroy(
824837
{
825838
struct xfs_ail *ailp = mp->m_ail;
826839

827-
cancel_delayed_work_sync(&ailp->xa_work);
840+
kthread_stop(ailp->xa_task);
828841
kmem_free(ailp);
829842
}

fs/xfs/xfs_trans_priv.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,23 +64,17 @@ struct xfs_ail_cursor {
6464
*/
6565
struct xfs_ail {
6666
struct xfs_mount *xa_mount;
67+
struct task_struct *xa_task;
6768
struct list_head xa_ail;
6869
xfs_lsn_t xa_target;
6970
struct list_head xa_cursors;
7071
spinlock_t xa_lock;
71-
struct delayed_work xa_work;
7272
xfs_lsn_t xa_last_pushed_lsn;
73-
unsigned long xa_flags;
7473
};
7574

76-
#define XFS_AIL_PUSHING_BIT 0
77-
7875
/*
7976
* From xfs_trans_ail.c
8077
*/
81-
82-
extern struct workqueue_struct *xfs_ail_wq; /* AIL workqueue */
83-
8478
void xfs_trans_ail_update_bulk(struct xfs_ail *ailp,
8579
struct xfs_ail_cursor *cur,
8680
struct xfs_log_item **log_items, int nr_items,

0 commit comments

Comments
 (0)