diff options
author | Bob Peterson <rpeterso@redhat.com> | 2017-01-25 12:50:47 -0500 |
---|---|---|
committer | Bob Peterson <rpeterso@redhat.com> | 2017-01-27 08:20:13 -0500 |
commit | 9862ca056e654633e521b303f74fb123f7f17e98 (patch) | |
tree | 313e2ce19c02ded366c2974f9480fc94e96cb430 | |
parent | b63f5e84826b3e1ae81e051a6a7c5a94b657aecb (diff) |
GFS2: Switch tr_touched to flag in transaction
This patch eliminates the int variable tr_touched in favor of a
new flag in the transaction. This is a step toward reducing contention
on the gfs2_log_lock spin_lock.
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
-rw-r--r-- | fs/gfs2/incore.h | 10 | ||||
-rw-r--r-- | fs/gfs2/log.c | 6 | ||||
-rw-r--r-- | fs/gfs2/meta_io.c | 6 | ||||
-rw-r--r-- | fs/gfs2/trans.c | 19 |
4 files changed, 23 insertions, 18 deletions
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 00d8dc20ea3a..c45084ac642d 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -470,15 +470,19 @@ struct gfs2_quota_data { | |||
470 | struct rcu_head qd_rcu; | 470 | struct rcu_head qd_rcu; |
471 | }; | 471 | }; |
472 | 472 | ||
473 | enum { | ||
474 | TR_TOUCHED = 1, | ||
475 | TR_ATTACHED = 2, | ||
476 | TR_ALLOCED = 3, | ||
477 | }; | ||
478 | |||
473 | struct gfs2_trans { | 479 | struct gfs2_trans { |
474 | unsigned long tr_ip; | 480 | unsigned long tr_ip; |
475 | 481 | ||
476 | unsigned int tr_blocks; | 482 | unsigned int tr_blocks; |
477 | unsigned int tr_revokes; | 483 | unsigned int tr_revokes; |
478 | unsigned int tr_reserved; | 484 | unsigned int tr_reserved; |
479 | unsigned int tr_touched:1; | 485 | unsigned long tr_flags; |
480 | unsigned int tr_attached:1; | ||
481 | unsigned int tr_alloced:1; | ||
482 | 486 | ||
483 | unsigned int tr_num_buf_new; | 487 | unsigned int tr_num_buf_new; |
484 | unsigned int tr_num_databuf_new; | 488 | unsigned int tr_num_databuf_new; |
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 5028a9d00c17..4fb76c04e65b 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -799,7 +799,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, | |||
799 | 799 | ||
800 | static void gfs2_merge_trans(struct gfs2_trans *old, struct gfs2_trans *new) | 800 | static void gfs2_merge_trans(struct gfs2_trans *old, struct gfs2_trans *new) |
801 | { | 801 | { |
802 | WARN_ON_ONCE(old->tr_attached != 1); | 802 | WARN_ON_ONCE(!test_bit(TR_ATTACHED, &old->tr_flags)); |
803 | 803 | ||
804 | old->tr_num_buf_new += new->tr_num_buf_new; | 804 | old->tr_num_buf_new += new->tr_num_buf_new; |
805 | old->tr_num_databuf_new += new->tr_num_databuf_new; | 805 | old->tr_num_databuf_new += new->tr_num_databuf_new; |
@@ -823,9 +823,9 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | |||
823 | if (sdp->sd_log_tr) { | 823 | if (sdp->sd_log_tr) { |
824 | gfs2_merge_trans(sdp->sd_log_tr, tr); | 824 | gfs2_merge_trans(sdp->sd_log_tr, tr); |
825 | } else if (tr->tr_num_buf_new || tr->tr_num_databuf_new) { | 825 | } else if (tr->tr_num_buf_new || tr->tr_num_databuf_new) { |
826 | gfs2_assert_withdraw(sdp, tr->tr_alloced); | 826 | gfs2_assert_withdraw(sdp, test_bit(TR_ALLOCED, &tr->tr_flags)); |
827 | sdp->sd_log_tr = tr; | 827 | sdp->sd_log_tr = tr; |
828 | tr->tr_attached = 1; | 828 | set_bit(TR_ATTACHED, &tr->tr_flags); |
829 | } | 829 | } |
830 | 830 | ||
831 | sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; | 831 | sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 373639a59782..a88a347cffe3 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -293,7 +293,7 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, | |||
293 | wait_on_buffer(bh); | 293 | wait_on_buffer(bh); |
294 | if (unlikely(!buffer_uptodate(bh))) { | 294 | if (unlikely(!buffer_uptodate(bh))) { |
295 | struct gfs2_trans *tr = current->journal_info; | 295 | struct gfs2_trans *tr = current->journal_info; |
296 | if (tr && tr->tr_touched) | 296 | if (tr && test_bit(TR_TOUCHED, &tr->tr_flags)) |
297 | gfs2_io_error_bh(sdp, bh); | 297 | gfs2_io_error_bh(sdp, bh); |
298 | brelse(bh); | 298 | brelse(bh); |
299 | *bhp = NULL; | 299 | *bhp = NULL; |
@@ -320,7 +320,7 @@ int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh) | |||
320 | 320 | ||
321 | if (!buffer_uptodate(bh)) { | 321 | if (!buffer_uptodate(bh)) { |
322 | struct gfs2_trans *tr = current->journal_info; | 322 | struct gfs2_trans *tr = current->journal_info; |
323 | if (tr && tr->tr_touched) | 323 | if (tr && test_bit(TR_TOUCHED, &tr->tr_flags)) |
324 | gfs2_io_error_bh(sdp, bh); | 324 | gfs2_io_error_bh(sdp, bh); |
325 | return -EIO; | 325 | return -EIO; |
326 | } | 326 | } |
@@ -346,7 +346,7 @@ void gfs2_remove_from_journal(struct buffer_head *bh, int meta) | |||
346 | tr->tr_num_buf_rm++; | 346 | tr->tr_num_buf_rm++; |
347 | else | 347 | else |
348 | tr->tr_num_databuf_rm++; | 348 | tr->tr_num_databuf_rm++; |
349 | tr->tr_touched = 1; | 349 | set_bit(TR_TOUCHED, &tr->tr_flags); |
350 | was_pinned = 1; | 350 | was_pinned = 1; |
351 | brelse(bh); | 351 | brelse(bh); |
352 | } | 352 | } |
diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c index 0c1bde395062..5d7f5b08d600 100644 --- a/fs/gfs2/trans.c +++ b/fs/gfs2/trans.c | |||
@@ -48,7 +48,7 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks, | |||
48 | tr->tr_blocks = blocks; | 48 | tr->tr_blocks = blocks; |
49 | tr->tr_revokes = revokes; | 49 | tr->tr_revokes = revokes; |
50 | tr->tr_reserved = 1; | 50 | tr->tr_reserved = 1; |
51 | tr->tr_alloced = 1; | 51 | set_bit(TR_ALLOCED, &tr->tr_flags); |
52 | if (blocks) | 52 | if (blocks) |
53 | tr->tr_reserved += 6 + blocks; | 53 | tr->tr_reserved += 6 + blocks; |
54 | if (revokes) | 54 | if (revokes) |
@@ -78,7 +78,8 @@ static void gfs2_print_trans(const struct gfs2_trans *tr) | |||
78 | { | 78 | { |
79 | pr_warn("Transaction created at: %pSR\n", (void *)tr->tr_ip); | 79 | pr_warn("Transaction created at: %pSR\n", (void *)tr->tr_ip); |
80 | pr_warn("blocks=%u revokes=%u reserved=%u touched=%u\n", | 80 | pr_warn("blocks=%u revokes=%u reserved=%u touched=%u\n", |
81 | tr->tr_blocks, tr->tr_revokes, tr->tr_reserved, tr->tr_touched); | 81 | tr->tr_blocks, tr->tr_revokes, tr->tr_reserved, |
82 | test_bit(TR_TOUCHED, &tr->tr_flags)); | ||
82 | pr_warn("Buf %u/%u Databuf %u/%u Revoke %u/%u\n", | 83 | pr_warn("Buf %u/%u Databuf %u/%u Revoke %u/%u\n", |
83 | tr->tr_num_buf_new, tr->tr_num_buf_rm, | 84 | tr->tr_num_buf_new, tr->tr_num_buf_rm, |
84 | tr->tr_num_databuf_new, tr->tr_num_databuf_rm, | 85 | tr->tr_num_databuf_new, tr->tr_num_databuf_rm, |
@@ -89,12 +90,12 @@ void gfs2_trans_end(struct gfs2_sbd *sdp) | |||
89 | { | 90 | { |
90 | struct gfs2_trans *tr = current->journal_info; | 91 | struct gfs2_trans *tr = current->journal_info; |
91 | s64 nbuf; | 92 | s64 nbuf; |
92 | int alloced = tr->tr_alloced; | 93 | int alloced = test_bit(TR_ALLOCED, &tr->tr_flags); |
93 | 94 | ||
94 | BUG_ON(!tr); | 95 | BUG_ON(!tr); |
95 | current->journal_info = NULL; | 96 | current->journal_info = NULL; |
96 | 97 | ||
97 | if (!tr->tr_touched) { | 98 | if (!test_bit(TR_TOUCHED, &tr->tr_flags)) { |
98 | gfs2_log_release(sdp, tr->tr_reserved); | 99 | gfs2_log_release(sdp, tr->tr_reserved); |
99 | if (alloced) { | 100 | if (alloced) { |
100 | kfree(tr); | 101 | kfree(tr); |
@@ -112,8 +113,8 @@ void gfs2_trans_end(struct gfs2_sbd *sdp) | |||
112 | gfs2_print_trans(tr); | 113 | gfs2_print_trans(tr); |
113 | 114 | ||
114 | gfs2_log_commit(sdp, tr); | 115 | gfs2_log_commit(sdp, tr); |
115 | if (alloced && !tr->tr_attached) | 116 | if (alloced && !test_bit(TR_ATTACHED, &tr->tr_flags)) |
116 | kfree(tr); | 117 | kfree(tr); |
117 | up_read(&sdp->sd_log_flush_lock); | 118 | up_read(&sdp->sd_log_flush_lock); |
118 | 119 | ||
119 | if (sdp->sd_vfs->s_flags & MS_SYNCHRONOUS) | 120 | if (sdp->sd_vfs->s_flags & MS_SYNCHRONOUS) |
@@ -182,7 +183,7 @@ void gfs2_trans_add_data(struct gfs2_glock *gl, struct buffer_head *bh) | |||
182 | gfs2_log_lock(sdp); | 183 | gfs2_log_lock(sdp); |
183 | } | 184 | } |
184 | gfs2_assert(sdp, bd->bd_gl == gl); | 185 | gfs2_assert(sdp, bd->bd_gl == gl); |
185 | tr->tr_touched = 1; | 186 | set_bit(TR_TOUCHED, &tr->tr_flags); |
186 | if (list_empty(&bd->bd_list)) { | 187 | if (list_empty(&bd->bd_list)) { |
187 | set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); | 188 | set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); |
188 | set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); | 189 | set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); |
@@ -201,7 +202,7 @@ static void meta_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) | |||
201 | enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state); | 202 | enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state); |
202 | 203 | ||
203 | tr = current->journal_info; | 204 | tr = current->journal_info; |
204 | tr->tr_touched = 1; | 205 | set_bit(TR_TOUCHED, &tr->tr_flags); |
205 | if (!list_empty(&bd->bd_list)) | 206 | if (!list_empty(&bd->bd_list)) |
206 | return; | 207 | return; |
207 | set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); | 208 | set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); |
@@ -256,7 +257,7 @@ void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) | |||
256 | 257 | ||
257 | BUG_ON(!list_empty(&bd->bd_list)); | 258 | BUG_ON(!list_empty(&bd->bd_list)); |
258 | gfs2_add_revoke(sdp, bd); | 259 | gfs2_add_revoke(sdp, bd); |
259 | tr->tr_touched = 1; | 260 | set_bit(TR_TOUCHED, &tr->tr_flags); |
260 | tr->tr_num_revoke++; | 261 | tr->tr_num_revoke++; |
261 | } | 262 | } |
262 | 263 | ||