Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ocfs2: adjust enabling place for la window

Patch series "improve write IO performance when fragmentation is high",
v6.


This patch (of 4):

After introducing gd->bg_contig_free_bits, the code path
'ocfs2_cluster_group_search() => ocfs2_local_alloc_seen_free_bits()'
becomes death when all the gd->bg_contig_free_bits are set to the correct
value. This patch relocates ocfs2_local_alloc_seen_free_bits() to a more
appropriate location. (The new place being ocfs2_block_group_set_bits().)

In ocfs2_local_alloc_seen_free_bits(), the scope of the spin-lock has been
adjusted to reduce meaningless lock races. e.g: when userspace creates &
deletes 1 cluster_size files in parallel, acquiring the spin-lock in
ocfs2_local_alloc_seen_free_bits() is totally pointless and impedes IO
performance.

Link: https://lkml.kernel.org/r/20240328125203.20892-3-heming.zhao@suse.com
Signed-off-by: Heming Zhao <heming.zhao@suse.com>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Gang He <ghe@suse.com>
Cc: Jun Piao <piaojun@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Heming Zhao and committed by
Andrew Morton
f51dac02 4eb7b93e

+8 -12
+6 -5
fs/ocfs2/localalloc.c
··· 212 212 void ocfs2_local_alloc_seen_free_bits(struct ocfs2_super *osb, 213 213 unsigned int num_clusters) 214 214 { 215 - spin_lock(&osb->osb_lock); 216 - if (osb->local_alloc_state == OCFS2_LA_DISABLED || 217 - osb->local_alloc_state == OCFS2_LA_THROTTLED) 218 - if (num_clusters >= osb->local_alloc_default_bits) { 215 + if (num_clusters >= osb->local_alloc_default_bits) { 216 + spin_lock(&osb->osb_lock); 217 + if (osb->local_alloc_state == OCFS2_LA_DISABLED || 218 + osb->local_alloc_state == OCFS2_LA_THROTTLED) { 219 219 cancel_delayed_work(&osb->la_enable_wq); 220 220 osb->local_alloc_state = OCFS2_LA_ENABLED; 221 221 } 222 - spin_unlock(&osb->osb_lock); 222 + spin_unlock(&osb->osb_lock); 223 + } 223 224 } 224 225 225 226 void ocfs2_la_enable_worker(struct work_struct *work)
+2 -7
fs/ocfs2/suballoc.c
··· 1372 1372 int journal_type = OCFS2_JOURNAL_ACCESS_WRITE; 1373 1373 unsigned int start = bit_off + num_bits; 1374 1374 u16 contig_bits; 1375 + struct ocfs2_super *osb = OCFS2_SB(alloc_inode->i_sb); 1375 1376 1376 1377 /* All callers get the descriptor via 1377 1378 * ocfs2_read_group_descriptor(). Any corruption is a code bug. */ ··· 1422 1421 if (contig_bits > max_contig_bits) 1423 1422 max_contig_bits = contig_bits; 1424 1423 bg->bg_contig_free_bits = cpu_to_le16(max_contig_bits); 1424 + ocfs2_local_alloc_seen_free_bits(osb, max_contig_bits); 1425 1425 } else { 1426 1426 bg->bg_contig_free_bits = 0; 1427 1427 } ··· 1589 1587 * of bits. */ 1590 1588 if (min_bits <= res->sr_bits) 1591 1589 search = 0; /* success */ 1592 - else if (res->sr_bits) { 1593 - /* 1594 - * Don't show bits which we'll be returning 1595 - * for allocation to the local alloc bitmap. 1596 - */ 1597 - ocfs2_local_alloc_seen_free_bits(osb, res->sr_bits); 1598 - } 1599 1590 } 1600 1591 1601 1592 return search;