Prepare to reduce locking by using atomic 32 bit access to the fields.
To ensure this we need to use the _ONCE macros.

https://virtuozzo.atlassian.net/browse/VSTOR-91659
Signed-off-by: Alexander Atanasov <alexander.atana...@virtuozzo.com>
---
 drivers/md/dm-ploop-bat.c | 20 ++++++++++----------
 drivers/md/dm-ploop-cmd.c | 28 ++++++++++++++--------------
 drivers/md/dm-ploop-map.c | 24 +++++++++++++-----------
 drivers/md/dm-ploop.h     |  2 +-
 4 files changed, 38 insertions(+), 36 deletions(-)

diff --git a/drivers/md/dm-ploop-bat.c b/drivers/md/dm-ploop-bat.c
index f28bd5d7b322..886a05cdd23a 100644
--- a/drivers/md/dm-ploop-bat.c
+++ b/drivers/md/dm-ploop-bat.c
@@ -143,9 +143,9 @@ bool ploop_try_update_bat_entry(struct ploop *ploop, u32 
clu, u8 level, u32 dst_
 
        clu = ploop_bat_clu_idx_in_page(clu); /* relative offset */
 
-       if (md->bat_levels[clu] == level) {
+       if (READ_ONCE(md->bat_levels[clu]) == level) {
                bat_entries = md->kmpage;
-               bat_entries[clu] = dst_clu;
+               WRITE_ONCE(bat_entries[clu], dst_clu);
                return true;
        }
        return false;
@@ -287,11 +287,11 @@ static int ploop_convert_bat_entries(struct ploop *ploop, 
struct rb_root *md_roo
                page_id++;
 
                for (; i <= end; i++) {
-                       if (bat_entries[i] > max_file_clu)
+                       if (READ_ONCE(bat_entries[i]) > max_file_clu)
                                ret = -EPROTO;
-                       if (!bat_entries[i])
-                               bat_entries[i] = BAT_ENTRY_NONE;
-                       if (bat_entries[i] < bat_clusters)
+                       if (!READ_ONCE(bat_entries[i]))
+                               WRITE_ONCE(bat_entries[i], BAT_ENTRY_NONE);
+                       if (READ_ONCE(bat_entries[i]) < bat_clusters)
                                ret = -EXDEV;
                }
 
@@ -431,21 +431,21 @@ static void ploop_apply_delta_mappings(struct ploop 
*ploop,
                        if (clu == nr_be - 1)
                                stop = true;
 
-                       if (bat_entries[i] != BAT_ENTRY_NONE) {
+                       if (READ_ONCE(bat_entries[i]) != BAT_ENTRY_NONE) {
                                /* md0 is already populated */
                                WARN_ON_ONCE(md->id && is_top_level);
                                goto set_not_hole;
                        }
 
                        if (!is_raw)
-                               dst_clu = d_bat_entries[i];
+                               dst_clu = READ_ONCE(d_bat_entries[i]);
                        else
                                dst_clu = clu;
 
                        if (dst_clu == BAT_ENTRY_NONE)
                                continue;
-                       md->bat_levels[i] = level;
-                       bat_entries[i] = dst_clu;
+                       WRITE_ONCE(md->bat_levels[i], level);
+                       WRITE_ONCE(bat_entries[i], dst_clu);
 set_not_hole:
                        if (is_top_level)
                                ploop_set_not_hole(ploop, bat_entries[i]);
diff --git a/drivers/md/dm-ploop-cmd.c b/drivers/md/dm-ploop-cmd.c
index d9d41d79d937..25ca9db4eeb8 100644
--- a/drivers/md/dm-ploop-cmd.c
+++ b/drivers/md/dm-ploop-cmd.c
@@ -47,7 +47,7 @@ static void ploop_advance_holes_bitmap(struct ploop *ploop,
                for (; i <= end; i++) {
                        if (!ploop_md_page_cluster_is_in_top_delta(ploop, md, 
i))
                                continue;
-                       dst_clu = bat_entries[i];
+                       dst_clu = READ_ONCE(bat_entries[i]);
                        /* This may happen after grow->shrink->(now) grow */
                        if (dst_clu < ploop->hb_nr &&
                            test_bit(dst_clu, ploop->holes_bitmap)) {
@@ -162,7 +162,7 @@ static u32 ploop_find_bat_entry(struct ploop *ploop, u32 
dst_clu, bool *is_locke
                ploop_init_be_iter(ploop, md->id, &i, &end);
                bat_entries = md->kmpage;
                for (; i <= end; i++) {
-                       if (bat_entries[i] != dst_clu)
+                       if (READ_ONCE(bat_entries[i]) != dst_clu)
                                continue;
                        if (ploop_md_page_cluster_is_in_top_delta(ploop, md, 
i)) {
                                clu = ploop_page_clu_idx_to_bat_clu(md->id, i);
@@ -735,17 +735,17 @@ static void notify_delta_merged(struct ploop *ploop, u8 
level,
                                stop = true;
 
                        /* deltas above @level become renumbered */
-                       if (bat_entries[i] != BAT_ENTRY_NONE &&
-                           md->bat_levels[i] > level) {
+                       if (READ_ONCE(bat_entries[i]) != BAT_ENTRY_NONE &&
+                           READ_ONCE(md->bat_levels[i]) > level) {
                                md->bat_levels[i]--;
                                continue;
                        }
 
-                       if (bat_entries[i] != BAT_ENTRY_NONE &&
-                            md->bat_levels[i] < level)
+                       if (READ_ONCE(bat_entries[i]) != BAT_ENTRY_NONE &&
+                            READ_ONCE(md->bat_levels[i]) < level)
                                continue;
 
-                       if (d_bat_entries[i] == BAT_ENTRY_NONE) {
+                       if (READ_ONCE(d_bat_entries[i]) == BAT_ENTRY_NONE) {
                                WARN_ON_ONCE(bat_entries[i] != BAT_ENTRY_NONE);
                                continue;
                        }
@@ -757,9 +757,9 @@ static void notify_delta_merged(struct ploop *ploop, u8 
level,
                         */
                        WRITE_ONCE(bat_entries[i], READ_ONCE(d_bat_entries[i]));
                        if (!forward)
-                               md->bat_levels[i] = level - 1;
+                               WRITE_ONCE(md->bat_levels[i], level - 1);
                        else
-                               md->bat_levels[i] = level;
+                               WRITE_ONCE(md->bat_levels[i], level);
                }
                if (stop)
                        break;
@@ -985,13 +985,13 @@ static int process_flip_upper_deltas(struct ploop *ploop)
                ploop_init_be_iter(ploop, md->id, &i, &end);
                bat_entries = md->kmpage;
                for (; i <= end; i++) {
-                       if (bat_entries[i] == BAT_ENTRY_NONE)
+                       if (READ_ONCE(bat_entries[i]) == BAT_ENTRY_NONE)
                                continue;
-                       if (md->bat_levels[i] == level) {
-                               md->bat_levels[i] = ploop_top_level(ploop);
+                       if (READ_ONCE(md->bat_levels[i]) == level) {
+                               WRITE_ONCE(md->bat_levels[i], 
ploop_top_level(ploop));
                                clear_bit(bat_entries[i], holes_bitmap);
-                       } else if (md->bat_levels[i] == ploop_top_level(ploop)) 
{
-                               md->bat_levels[i] = level;
+                       } else if (READ_ONCE(md->bat_levels[i]) == 
ploop_top_level(ploop)) {
+                               WRITE_ONCE(md->bat_levels[i], level);
                        }
                }
        }
diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index 634f0679be3f..221e97ba84a9 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -723,9 +723,9 @@ static void ploop_release_cluster(struct ploop *ploop, u32 
clu)
        clu = ploop_bat_clu_idx_in_page(clu); /* relative to page */
 
        bat_entries = md->kmpage;
-       dst_clu = bat_entries[clu];
-       bat_entries[clu] = BAT_ENTRY_NONE;
-       md->bat_levels[clu] = 0;
+       dst_clu = READ_ONCE(bat_entries[clu]);
+       WRITE_ONCE(bat_entries[clu], BAT_ENTRY_NONE);
+       WRITE_ONCE(md->bat_levels[clu], 0);
 
        ploop_hole_set_bit(dst_clu, ploop);
 }
@@ -793,8 +793,8 @@ static void ploop_advance_local_after_bat_wb(struct ploop 
*ploop,
                }
 
                if (success) {
-                       bat_entries[i] = dst_clu[i];
-                       md->bat_levels[i] = ploop_top_level(ploop);
+                       WRITE_ONCE(bat_entries[i], READ_ONCE(dst_clu[i]));
+                       WRITE_ONCE(md->bat_levels[i], ploop_top_level(ploop));
                } else {
                        ploop_hole_set_bit(i + off, ploop);
                }
@@ -977,7 +977,7 @@ static void ploop_bat_page_zero_cluster(struct ploop *ploop,
        clu = ploop_bat_clu_idx_in_page(clu);
 
        to = kmap_local_page(piwb->bat_page);
-       to[clu] = 0;
+       WRITE_ONCE(to[clu], 0);
        kunmap_local(to);
 }
 
@@ -1085,14 +1085,16 @@ static int ploop_alloc_cluster(struct ploop *ploop, 
struct ploop_index_wb *piwb,
        bool already_alloced = false;
        map_index_t *to;
        int ret = 0;
+       u32 tmp_clu;
 
        /* Cluster index related to the page[page_id] start */
        clu -= piwb->page_id * PAGE_SIZE / sizeof(map_index_t) - 
PLOOP_MAP_OFFSET;
 
        to = kmap_local_page(piwb->bat_page);
-       if (to[clu]) {
+       tmp_clu = READ_ONCE(to[clu]);
+       if (tmp_clu) {
                /* Already mapped by one of previous bios */
-               *dst_clu = to[clu];
+               *dst_clu = tmp_clu;
                already_alloced = true;
        }
        kunmap_local(to);
@@ -1105,7 +1107,7 @@ static int ploop_alloc_cluster(struct ploop *ploop, 
struct ploop_index_wb *piwb,
                goto out;
 
        to = kmap_local_page(piwb->bat_page);
-       to[clu] = *dst_clu;
+       WRITE_ONCE(to[clu], *dst_clu);
        kunmap_local(to);
 out:
        return ret;
@@ -1388,7 +1390,7 @@ static void ploop_submit_cow_index_wb(struct ploop_cow 
*cow)
 
        to = kmap_local_page(piwb->bat_page);
        WARN_ON(to[clu]);
-       to[clu] = cow->dst_clu;
+       WRITE_ONCE(to[clu], cow->dst_clu);
        kunmap_local(to);
 
        /* Prevent double clearing of holes_bitmap bit on complete_cow() */
@@ -1725,7 +1727,7 @@ static void ploop_process_one_discard_pio(struct ploop 
*ploop, struct pio *pio)
                pio->bi_status = BLK_STS_IOERR;
                goto err;
        } else {
-               to[clu] = 0;
+               WRITE_ONCE(to[clu], 0);
                list_add_tail(&pio->list, &piwb->ready_data_pios);
        }
        kunmap_local(to);
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index 3783d42a6162..b42baccf9a00 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -427,7 +427,7 @@ static inline u32 ploop_bat_entries(struct ploop *ploop, 
u32 clu,
        clu = ploop_bat_clu_idx_in_page(clu);
 
        if (bat_level)
-               *bat_level = md->bat_levels[clu];
+               *bat_level = READ_ONCE(md->bat_levels[clu]);
        if (md_ret)
                *md_ret = md;
 
-- 
2.43.0

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to