Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e84d0a4f authored by Wu Fengguang's avatar Wu Fengguang
Browse files

writeback: trace event writeback_queue_io



Note that it adds a little overheads to account the moved/enqueued
inodes from b_dirty to b_io. The "moved" accounting may be later used to
limit the number of inodes that can be moved in one shot, in order to
keep spinlock hold time under control.

Signed-off-by: default avatarWu Fengguang <fengguang.wu@intel.com>
parent 251d6a47
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -248,7 +248,7 @@ static bool inode_dirtied_after(struct inode *inode, unsigned long t)
/*
 * Move expired dirty inodes from @delaying_queue to @dispatch_queue.
 */
static void move_expired_inodes(struct list_head *delaying_queue,
static int move_expired_inodes(struct list_head *delaying_queue,
			       struct list_head *dispatch_queue,
			       unsigned long *older_than_this)
{
@@ -257,6 +257,7 @@ static void move_expired_inodes(struct list_head *delaying_queue,
	struct super_block *sb = NULL;
	struct inode *inode;
	int do_sb_sort = 0;
	int moved = 0;

	while (!list_empty(delaying_queue)) {
		inode = wb_inode(delaying_queue->prev);
@@ -267,12 +268,13 @@ static void move_expired_inodes(struct list_head *delaying_queue,
			do_sb_sort = 1;
		sb = inode->i_sb;
		list_move(&inode->i_wb_list, &tmp);
		moved++;
	}

	/* just one sb in list, splice to dispatch_queue and we're done */
	if (!do_sb_sort) {
		list_splice(&tmp, dispatch_queue);
		return;
		goto out;
	}

	/* Move inodes from one superblock together */
@@ -284,6 +286,8 @@ static void move_expired_inodes(struct list_head *delaying_queue,
				list_move(&inode->i_wb_list, dispatch_queue);
		}
	}
out:
	return moved;
}

/*
@@ -299,9 +303,11 @@ static void move_expired_inodes(struct list_head *delaying_queue,
 */
static void queue_io(struct bdi_writeback *wb, unsigned long *older_than_this)
{
	int moved;
	assert_spin_locked(&wb->list_lock);
	list_splice_init(&wb->b_more_io, &wb->b_io);
	move_expired_inodes(&wb->b_dirty, &wb->b_io, older_than_this);
	moved = move_expired_inodes(&wb->b_dirty, &wb->b_io, older_than_this);
	trace_writeback_queue_io(wb, older_than_this, moved);
}

static int write_inode(struct inode *inode, struct writeback_control *wbc)
+25 −0
Original line number Diff line number Diff line
@@ -162,6 +162,31 @@ DEFINE_WBC_EVENT(wbc_balance_dirty_written);
DEFINE_WBC_EVENT(wbc_balance_dirty_wait);
DEFINE_WBC_EVENT(wbc_writepage);

TRACE_EVENT(writeback_queue_io,
	TP_PROTO(struct bdi_writeback *wb,
		 unsigned long *older_than_this,
		 int moved),
	TP_ARGS(wb, older_than_this, moved),
	TP_STRUCT__entry(
		__array(char,		name, 32)
		__field(unsigned long,	older)
		__field(long,		age)
		__field(int,		moved)
	),
	TP_fast_assign(
		strncpy(__entry->name, dev_name(wb->bdi->dev), 32);
		__entry->older	= older_than_this ?  *older_than_this : 0;
		__entry->age	= older_than_this ?
				  (jiffies - *older_than_this) * 1000 / HZ : -1;
		__entry->moved	= moved;
	),
	TP_printk("bdi %s: older=%lu age=%ld enqueue=%d",
		__entry->name,
		__entry->older,	/* older_than_this in jiffies */
		__entry->age,	/* older_than_this in relative milliseconds */
		__entry->moved)
);

DECLARE_EVENT_CLASS(writeback_congest_waited_template,

	TP_PROTO(unsigned int usec_timeout, unsigned int usec_delayed),