ocfs2: adjust enabling place for la window
authorHeming Zhao <heming.zhao@suse.com>
Thu, 28 Mar 2024 12:52:01 +0000 (20:52 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Fri, 26 Apr 2024 04:07:03 +0000 (21:07 -0700)
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>
fs/ocfs2/localalloc.c
fs/ocfs2/suballoc.c

index 33aeaaa056d70aa51651ce85eca8600fbb80c79c..c84ce53cdec03e4ba80668758d9275282c6b5b99 100644 (file)
@@ -212,14 +212,15 @@ static inline int ocfs2_la_state_enabled(struct ocfs2_super *osb)
 void ocfs2_local_alloc_seen_free_bits(struct ocfs2_super *osb,
                                      unsigned int num_clusters)
 {
-       spin_lock(&osb->osb_lock);
-       if (osb->local_alloc_state == OCFS2_LA_DISABLED ||
-           osb->local_alloc_state == OCFS2_LA_THROTTLED)
-               if (num_clusters >= osb->local_alloc_default_bits) {
+       if (num_clusters >= osb->local_alloc_default_bits) {
+               spin_lock(&osb->osb_lock);
+               if (osb->local_alloc_state == OCFS2_LA_DISABLED ||
+                   osb->local_alloc_state == OCFS2_LA_THROTTLED) {
                        cancel_delayed_work(&osb->la_enable_wq);
                        osb->local_alloc_state = OCFS2_LA_ENABLED;
                }
-       spin_unlock(&osb->osb_lock);
+               spin_unlock(&osb->osb_lock);
+       }
 }
 
 void ocfs2_la_enable_worker(struct work_struct *work)
index 7e30e9d7989060819b629cb18e63865cfb5c9b80..8314ec487cfb7caa4a7b2a928179d0b40a20ecdf 100644 (file)
@@ -1372,6 +1372,7 @@ int ocfs2_block_group_set_bits(handle_t *handle,
        int journal_type = OCFS2_JOURNAL_ACCESS_WRITE;
        unsigned int start = bit_off + num_bits;
        u16 contig_bits;
+       struct ocfs2_super *osb = OCFS2_SB(alloc_inode->i_sb);
 
        /* All callers get the descriptor via
         * ocfs2_read_group_descriptor().  Any corruption is a code bug. */
@@ -1421,6 +1422,7 @@ int ocfs2_block_group_set_bits(handle_t *handle,
                if (contig_bits > max_contig_bits)
                        max_contig_bits = contig_bits;
                bg->bg_contig_free_bits = cpu_to_le16(max_contig_bits);
+               ocfs2_local_alloc_seen_free_bits(osb, max_contig_bits);
        } else {
                bg->bg_contig_free_bits = 0;
        }
@@ -1587,13 +1589,6 @@ static int ocfs2_cluster_group_search(struct inode *inode,
                 * of bits. */
                if (min_bits <= res->sr_bits)
                        search = 0; /* success */
-               else if (res->sr_bits) {
-                       /*
-                        * Don't show bits which we'll be returning
-                        * for allocation to the local alloc bitmap.
-                        */
-                       ocfs2_local_alloc_seen_free_bits(osb, res->sr_bits);
-               }
        }
 
        return search;