GFS2: Add to tail, not head, of transaction
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/1 GFS2: Add to tail, not head, of transaction
Hi,
Before this patch, frunction gfs2_trans_add_meta called list_add to add a buffer to a transaction, tr_buf. Later, in the before_commit functions, it traversed the list in sequential order, which meant that they were processed in a sub-optimal order. For example, blocks could go out in 54321 order rather than 12345, causing media heads to bounce unnecessarily.
This makes no difference for small IO operations, but large writes benefit greatly when they add lots of indirect blocks to a transaction, and those blocks are allocated in ascending order, as the block allocator tries to do.
This patch changes it to list_add_tail so they are traversed (and therefore written back) in the same order as they are added to the transaction.
In one of the more extreme examples, I did a test where I had 10 simultaneous instances of iozone, each writing 25GB of data, using one of our performance testing machines. The results are:
Without the patch With the patch
----------------- ------------------
Children see throughput 1395068.00 kB/sec 1527073.61 kB/sec
Parent sees throughput 1348544.00 kB/sec 1485594.66 kB/secThese numbers are artificially inflated because I was also running with Andreas Gruenbacher's iomap-write patch set plus my rgrp sharing patch set in both these cases. Still, it shows a 9 percent performance boost for both children and parent throughput.
--- fs/gfs2/trans.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/gfs2/trans.c +1 -1
@@ -247,7 +247,7 @@ void gfs2_trans_add_meta(struct gfs2_glock *gl, struct buffer_head *bh)gfs2_pin (sdp, bd->bd_bh); mh->__pad0 =cpu_to_be64 (0 ); mh->mh_jid =cpu_to_be32 (sdp->sd_jdesc->jd_jid); -list_add (&bd->bd_list, &tr->tr_buf); +list_add_tail (&bd->bd_list, &tr->tr_buf); tr->tr_num_buf_new++; out_unlock:gfs2_log_unlock (sdp);
Andreas Gruenbacher
maintainerPATCH 1/1 GFS2: Add to tail, not head, of transaction
Quoted 8 lines · Bob Peterson
Hi,
Before this patch, frunction
gfs2_trans_add_metacalledlist_addto add a buffer to a transaction,tr_buf. Later, in thebefore_commitfunctions, it traversed the list in sequential order, which meant that they were processed in a sub-optimal order. For example, blocks could go out in 54321 order rather than 12345, causing media heads to bounce unnecessarily.
Hmm, the patch itself looks reasonable, but given that gfs2_before_commit sorts the list by block number before iterating it, the above explanation seems to be at least partially wrong. Could you please clarify what's really going on?
Quoted 34 lines
This makes no difference for small IO operations, but large writes benefit greatly when they add lots of indirect blocks to a transaction, and those blocks are allocated in ascending order, as the block allocator tries to do.
This patch changes it to
list_add_tailso they are traversed (and therefore written back) in the same order as they are added to the transaction.In one of the more extreme examples, I did a test where I had 10 simultaneous instances of iozone, each writing 25GB of data, using one of our performance testing machines. The results are:
Without the patch With the patch ----------------- ------------------ Children see throughput 1395068.00 kB/sec 1527073.61 kB/sec Parent sees throughput 1348544.00 kB/sec 1485594.66 kB/secThese numbers are artificially inflated because I was also running with Andreas Gruenbacher's iomap-write patch set plus my rgrp sharing patch set in both these cases. Still, it shows a 9 percent performance boost for both children and parent throughput.
Signed-off-by Bob Peterson <[email protected]>--- fs/gfs2/trans.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)fs/gfs2/trans.c +0
-0
fs/gfs2/trans.c void gfs2_trans_add_meta(struct gfs2_glock *gl, struct buffer_head *bh) · line 253
Quoted 8 lines
fs/gfs2/trans.c +1
-1@@ -247,7 +247,7 @@ void gfs2_trans_add_meta(struct gfs2_glock *gl, struct buffer_head *bh)gfs2_pin (sdp, bd->bd_bh); mh->__pad0 =cpu_to_be64 (0 ); mh->mh_jid =cpu_to_be32 (sdp->sd_jdesc->jd_jid); -list_add (&bd->bd_list, &tr->tr_buf); +list_add_tail (&bd->bd_list, &tr->tr_buf); tr->tr_num_buf_new++; out_unlock:gfs2_log_unlock (sdp);
Thanks,
Andreas