]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
md: Replace deprecated kmap_atomic() with kmap_local_page()
authorDavid Reaver <me@davidreaver.com>
Wed, 8 Jan 2025 19:21:30 +0000 (11:21 -0800)
committerSong Liu <song@kernel.org>
Mon, 13 Jan 2025 15:36:29 +0000 (07:36 -0800)
kmap_atomic() is deprecated and should be replaced with kmap_local_page()
[1][2]. kmap_local_page() is faster in kernels with HIGHMEM enabled, can
take page faults, and allows preemption.

According to [2], this is safe as long as the code between kmap_atomic()
and kunmap_atomic() does not implicitly depend on disabling page faults or
preemption. It appears to me that none of the call sites in this patch
depend on disabling page faults or preemption; they are all mapping a page
to simply extract some information from it or print some debug info.

[1] https://lwn.net/Articles/836144/
[2] https://docs.kernel.org/mm/highmem.html#temporary-virtual-mappings

Signed-off-by: David Reaver <me@davidreaver.com>
Link: https://lore.kernel.org/r/20250108192131.46843-1-me@davidreaver.com
Signed-off-by: Song Liu <song@kernel.org>
drivers/md/md-bitmap.c
drivers/md/raid5-cache.c

index c3a42dd66ce5514c7900059acfc80f8c8b312a1a..d16a89d673a179f0a71b586f8998adb88a46890f 100644 (file)
@@ -682,7 +682,7 @@ static void bitmap_update_sb(void *data)
                return;
        if (!bitmap->storage.sb_page) /* no superblock */
                return;
-       sb = kmap_atomic(bitmap->storage.sb_page);
+       sb = kmap_local_page(bitmap->storage.sb_page);
        sb->events = cpu_to_le64(bitmap->mddev->events);
        if (bitmap->mddev->events < bitmap->events_cleared)
                /* rocking back to read-only */
@@ -702,7 +702,7 @@ static void bitmap_update_sb(void *data)
        sb->nodes = cpu_to_le32(bitmap->mddev->bitmap_info.nodes);
        sb->sectors_reserved = cpu_to_le32(bitmap->mddev->
                                           bitmap_info.space);
-       kunmap_atomic(sb);
+       kunmap_local(sb);
 
        if (bitmap->storage.file)
                write_file_page(bitmap, bitmap->storage.sb_page, 1);
@@ -717,7 +717,7 @@ static void bitmap_print_sb(struct bitmap *bitmap)
 
        if (!bitmap || !bitmap->storage.sb_page)
                return;
-       sb = kmap_atomic(bitmap->storage.sb_page);
+       sb = kmap_local_page(bitmap->storage.sb_page);
        pr_debug("%s: bitmap file superblock:\n", bmname(bitmap));
        pr_debug("         magic: %08x\n", le32_to_cpu(sb->magic));
        pr_debug("       version: %u\n", le32_to_cpu(sb->version));
@@ -736,7 +736,7 @@ static void bitmap_print_sb(struct bitmap *bitmap)
        pr_debug("     sync size: %llu KB\n",
                 (unsigned long long)le64_to_cpu(sb->sync_size)/2);
        pr_debug("max write behind: %u\n", le32_to_cpu(sb->write_behind));
-       kunmap_atomic(sb);
+       kunmap_local(sb);
 }
 
 /*
@@ -760,7 +760,7 @@ static int md_bitmap_new_disk_sb(struct bitmap *bitmap)
                return -ENOMEM;
        bitmap->storage.sb_index = 0;
 
-       sb = kmap_atomic(bitmap->storage.sb_page);
+       sb = kmap_local_page(bitmap->storage.sb_page);
 
        sb->magic = cpu_to_le32(BITMAP_MAGIC);
        sb->version = cpu_to_le32(BITMAP_MAJOR_HI);
@@ -768,7 +768,7 @@ static int md_bitmap_new_disk_sb(struct bitmap *bitmap)
        chunksize = bitmap->mddev->bitmap_info.chunksize;
        BUG_ON(!chunksize);
        if (!is_power_of_2(chunksize)) {
-               kunmap_atomic(sb);
+               kunmap_local(sb);
                pr_warn("bitmap chunksize not a power of 2\n");
                return -EINVAL;
        }
@@ -803,7 +803,7 @@ static int md_bitmap_new_disk_sb(struct bitmap *bitmap)
        sb->events_cleared = cpu_to_le64(bitmap->mddev->events);
        bitmap->mddev->bitmap_info.nodes = 0;
 
-       kunmap_atomic(sb);
+       kunmap_local(sb);
 
        return 0;
 }
@@ -865,7 +865,7 @@ re_read:
                return err;
 
        err = -EINVAL;
-       sb = kmap_atomic(sb_page);
+       sb = kmap_local_page(sb_page);
 
        chunksize = le32_to_cpu(sb->chunksize);
        daemon_sleep = le32_to_cpu(sb->daemon_sleep) * HZ;
@@ -932,7 +932,7 @@ re_read:
        err = 0;
 
 out:
-       kunmap_atomic(sb);
+       kunmap_local(sb);
        if (err == 0 && nodes && (bitmap->cluster_slot < 0)) {
                /* Assigning chunksize is required for "re_read" */
                bitmap->mddev->bitmap_info.chunksize = chunksize;
@@ -1161,12 +1161,12 @@ static void md_bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
        bit = file_page_offset(&bitmap->storage, chunk);
 
        /* set the bit */
-       kaddr = kmap_atomic(page);
+       kaddr = kmap_local_page(page);
        if (test_bit(BITMAP_HOSTENDIAN, &bitmap->flags))
                set_bit(bit, kaddr);
        else
                set_bit_le(bit, kaddr);
-       kunmap_atomic(kaddr);
+       kunmap_local(kaddr);
        pr_debug("set file bit %lu page %lu\n", bit, index);
        /* record page number so it gets flushed to disk when unplug occurs */
        set_page_attr(bitmap, index - node_offset, BITMAP_PAGE_DIRTY);
@@ -1190,12 +1190,12 @@ static void md_bitmap_file_clear_bit(struct bitmap *bitmap, sector_t block)
        if (!page)
                return;
        bit = file_page_offset(&bitmap->storage, chunk);
-       paddr = kmap_atomic(page);
+       paddr = kmap_local_page(page);
        if (test_bit(BITMAP_HOSTENDIAN, &bitmap->flags))
                clear_bit(bit, paddr);
        else
                clear_bit_le(bit, paddr);
-       kunmap_atomic(paddr);
+       kunmap_local(paddr);
        if (!test_page_attr(bitmap, index - node_offset, BITMAP_PAGE_NEEDWRITE)) {
                set_page_attr(bitmap, index - node_offset, BITMAP_PAGE_PENDING);
                bitmap->allclean = 0;
@@ -1214,12 +1214,12 @@ static int md_bitmap_file_test_bit(struct bitmap *bitmap, sector_t block)
        if (!page)
                return -EINVAL;
        bit = file_page_offset(&bitmap->storage, chunk);
-       paddr = kmap_atomic(page);
+       paddr = kmap_local_page(page);
        if (test_bit(BITMAP_HOSTENDIAN, &bitmap->flags))
                set = test_bit(bit, paddr);
        else
                set = test_bit_le(bit, paddr);
-       kunmap_atomic(paddr);
+       kunmap_local(paddr);
        return set;
 }
 
@@ -1388,9 +1388,9 @@ static int md_bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
                         * If the bitmap is out of date, dirty the whole page
                         * and write it out
                         */
-                       paddr = kmap_atomic(page);
+                       paddr = kmap_local_page(page);
                        memset(paddr + offset, 0xff, PAGE_SIZE - offset);
-                       kunmap_atomic(paddr);
+                       kunmap_local(paddr);
 
                        filemap_write_page(bitmap, i, true);
                        if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags)) {
@@ -1406,12 +1406,12 @@ static int md_bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
                void *paddr;
                bool was_set;
 
-               paddr = kmap_atomic(page);
+               paddr = kmap_local_page(page);
                if (test_bit(BITMAP_HOSTENDIAN, &bitmap->flags))
                        was_set = test_bit(bit, paddr);
                else
                        was_set = test_bit_le(bit, paddr);
-               kunmap_atomic(paddr);
+               kunmap_local(paddr);
 
                if (was_set) {
                        /* if the disk bit is set, set the memory bit */
@@ -1546,10 +1546,10 @@ static void bitmap_daemon_work(struct mddev *mddev)
                bitmap_super_t *sb;
                bitmap->need_sync = 0;
                if (bitmap->storage.filemap) {
-                       sb = kmap_atomic(bitmap->storage.sb_page);
+                       sb = kmap_local_page(bitmap->storage.sb_page);
                        sb->events_cleared =
                                cpu_to_le64(bitmap->events_cleared);
-                       kunmap_atomic(sb);
+                       kunmap_local(sb);
                        set_page_attr(bitmap, 0,
                                      BITMAP_PAGE_NEEDWRITE);
                }
index b4f7b79fd187d0a8a4a26e049a261cc6f139cc1b..7a22cb2e5ac3869e9dfb9572d318330ed5d9f8b9 100644 (file)
@@ -1023,10 +1023,10 @@ int r5l_write_stripe(struct r5l_log *log, struct stripe_head *sh)
                /* checksum is already calculated in last run */
                if (test_bit(STRIPE_LOG_TRAPPED, &sh->state))
                        continue;
-               addr = kmap_atomic(sh->dev[i].page);
+               addr = kmap_local_page(sh->dev[i].page);
                sh->dev[i].log_checksum = crc32c_le(log->uuid_checksum,
                                                    addr, PAGE_SIZE);
-               kunmap_atomic(addr);
+               kunmap_local(addr);
        }
        parity_pages = 1 + !!(sh->qd_idx >= 0);
        data_pages = write_disks - parity_pages;
@@ -1979,9 +1979,9 @@ r5l_recovery_verify_data_checksum(struct r5l_log *log,
        u32 checksum;
 
        r5l_recovery_read_page(log, ctx, page, log_offset);
-       addr = kmap_atomic(page);
+       addr = kmap_local_page(page);
        checksum = crc32c_le(log->uuid_checksum, addr, PAGE_SIZE);
-       kunmap_atomic(addr);
+       kunmap_local(addr);
        return (le32_to_cpu(log_checksum) == checksum) ? 0 : -EINVAL;
 }
 
@@ -2381,11 +2381,11 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
                                payload->size = cpu_to_le32(BLOCK_SECTORS);
                                payload->location = cpu_to_le64(
                                        raid5_compute_blocknr(sh, i, 0));
-                               addr = kmap_atomic(dev->page);
+                               addr = kmap_local_page(dev->page);
                                payload->checksum[0] = cpu_to_le32(
                                        crc32c_le(log->uuid_checksum, addr,
                                                  PAGE_SIZE));
-                               kunmap_atomic(addr);
+                               kunmap_local(addr);
                                sync_page_io(log->rdev, write_pos, PAGE_SIZE,
                                             dev->page, REQ_OP_WRITE, false);
                                write_pos = r5l_ring_add(log, write_pos,
@@ -2888,10 +2888,10 @@ int r5c_cache_data(struct r5l_log *log, struct stripe_head *sh)
 
                if (!test_bit(R5_Wantwrite, &sh->dev[i].flags))
                        continue;
-               addr = kmap_atomic(sh->dev[i].page);
+               addr = kmap_local_page(sh->dev[i].page);
                sh->dev[i].log_checksum = crc32c_le(log->uuid_checksum,
                                                    addr, PAGE_SIZE);
-               kunmap_atomic(addr);
+               kunmap_local(addr);
                pages++;
        }
        WARN_ON(pages == 0);