Skip to content

Commit

Permalink
Merge branch 'kmap-conversion-for-5.12' of git://git.kernel.org/pub/s…
Browse files Browse the repository at this point in the history
…cm/linux/kernel/git/kdave/linux

Pull kmap conversion updates from David Sterba:
 "This contains changes regarding kmap API use and eg conversion from
  kmap_atomic to kmap_local_page.

  The API belongs to memory management but to save cross-tree
  dependency headaches we've agreed to take it through the btrfs tree
  because there are some trivial conversions possible, while the rest
  will need some time and getting the easy cases out of the way would be
  convenient.

  The changes can be grouped:

   - function exports, new helpers

   - new VM_BUG_ON for additional verification; it's been discussed if
     it should be VM_BUG_ON or BUG_ON, the former was chosen due to
     performance reasons

   - code replaced by relevant helpers"

[ This is an updated version of a request that originally came in during
  the merge window, but I asked for some updates:

    https://lore.kernel.org/lkml/[email protected]/

  which is why this got merge after the merge window closed.  - Linus ]

* 'kmap-conversion-for-5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: use copy_highpage() instead of 2 kmaps()
  btrfs: use memcpy_[to|from]_page() and kmap_local_page()
  mm/highmem: Add VM_BUG_ON() to mem*_page() calls
  mm/highmem: Introduce memcpy_page(), memmove_page(), and memset_page()
  mm/highmem: Convert memcpy_[to|from]_page() to kmap_local_page()
  mm/highmem: Lift memcpy_[to|from]_page to core
  • Loading branch information
torvalds committed Mar 1, 2021
2 parents c608aca + 80cc838 commit 7a7fd0d
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 46 deletions.
6 changes: 2 additions & 4 deletions fs/btrfs/compression.c
Original file line number Diff line number Diff line change
Expand Up @@ -1261,7 +1261,6 @@ int btrfs_decompress_buf2page(const char *buf, unsigned long buf_start,
unsigned long prev_start_byte;
unsigned long working_bytes = total_out - buf_start;
unsigned long bytes;
char *kaddr;
struct bio_vec bvec = bio_iter_iovec(bio, bio->bi_iter);

/*
Expand Down Expand Up @@ -1292,9 +1291,8 @@ int btrfs_decompress_buf2page(const char *buf, unsigned long buf_start,
PAGE_SIZE - (buf_offset % PAGE_SIZE));
bytes = min(bytes, working_bytes);

kaddr = kmap_atomic(bvec.bv_page);
memcpy(kaddr + bvec.bv_offset, buf + buf_offset, bytes);
kunmap_atomic(kaddr);
memcpy_to_page(bvec.bv_page, bvec.bv_offset, buf + buf_offset,
bytes);
flush_dcache_page(bvec.bv_page);

buf_offset += bytes;
Expand Down
4 changes: 2 additions & 2 deletions fs/btrfs/lzo.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ int lzo_decompress(struct list_head *ws, unsigned char *data_in,
destlen = min_t(unsigned long, destlen, PAGE_SIZE);
bytes = min_t(unsigned long, destlen, out_len - start_byte);

kaddr = kmap_atomic(dest_page);
kaddr = kmap_local_page(dest_page);
memcpy(kaddr, workspace->buf + start_byte, bytes);

/*
Expand All @@ -477,7 +477,7 @@ int lzo_decompress(struct list_head *ws, unsigned char *data_in,
*/
if (bytes < destlen)
memset(kaddr+bytes, 0, destlen-bytes);
kunmap_atomic(kaddr);
kunmap_local(kaddr);
out:
return ret;
}
Expand Down
10 changes: 1 addition & 9 deletions fs/btrfs/raid56.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,6 @@ int btrfs_alloc_stripe_hash_table(struct btrfs_fs_info *info)
static void cache_rbio_pages(struct btrfs_raid_bio *rbio)
{
int i;
char *s;
char *d;
int ret;

ret = alloc_rbio_pages(rbio);
Expand All @@ -261,13 +259,7 @@ static void cache_rbio_pages(struct btrfs_raid_bio *rbio)
if (!rbio->bio_pages[i])
continue;

s = kmap(rbio->bio_pages[i]);
d = kmap(rbio->stripe_pages[i]);

copy_page(d, s);

kunmap(rbio->bio_pages[i]);
kunmap(rbio->stripe_pages[i]);
copy_highpage(rbio->stripe_pages[i], rbio->bio_pages[i]);
SetPageUptodate(rbio->stripe_pages[i]);
}
set_bit(RBIO_CACHE_READY_BIT, &rbio->flags);
Expand Down
6 changes: 1 addition & 5 deletions fs/btrfs/reflink.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,8 @@ static int copy_inline_to_page(struct btrfs_inode *inode,
set_bit(BTRFS_INODE_NO_DELALLOC_FLUSH, &inode->runtime_flags);

if (comp_type == BTRFS_COMPRESS_NONE) {
char *map;

map = kmap(page);
memcpy(map, data_start, datal);
memcpy_to_page(page, 0, data_start, datal);
flush_dcache_page(page);
kunmap(page);
} else {
ret = btrfs_decompress(comp_type, data_start, page, 0,
inline_size, datal);
Expand Down
7 changes: 2 additions & 5 deletions fs/btrfs/send.c
Original file line number Diff line number Diff line change
Expand Up @@ -4932,7 +4932,6 @@ static int put_file_data(struct send_ctx *sctx, u64 offset, u32 len)
struct btrfs_fs_info *fs_info = root->fs_info;
struct inode *inode;
struct page *page;
char *addr;
pgoff_t index = offset >> PAGE_SHIFT;
pgoff_t last_index;
unsigned pg_offset = offset_in_page(offset);
Expand Down Expand Up @@ -4985,10 +4984,8 @@ static int put_file_data(struct send_ctx *sctx, u64 offset, u32 len)
}
}

addr = kmap(page);
memcpy(sctx->send_buf + sctx->send_size, addr + pg_offset,
cur_len);
kunmap(page);
memcpy_from_page(sctx->send_buf + sctx->send_size, page,
pg_offset, cur_len);
unlock_page(page);
put_page(page);
index++;
Expand Down
5 changes: 2 additions & 3 deletions fs/btrfs/zlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,9 +432,8 @@ int zlib_decompress(struct list_head *ws, unsigned char *data_in,
PAGE_SIZE - (buf_offset % PAGE_SIZE));
bytes = min(bytes, bytes_left);

kaddr = kmap_atomic(dest_page);
memcpy(kaddr + pg_offset, workspace->buf + buf_offset, bytes);
kunmap_atomic(kaddr);
memcpy_to_page(dest_page, pg_offset,
workspace->buf + buf_offset, bytes);

pg_offset += bytes;
bytes_left -= bytes;
Expand Down
6 changes: 2 additions & 4 deletions fs/btrfs/zstd.c
Original file line number Diff line number Diff line change
Expand Up @@ -688,10 +688,8 @@ int zstd_decompress(struct list_head *ws, unsigned char *data_in,
bytes = min_t(unsigned long, destlen - pg_offset,
workspace->out_buf.size - buf_offset);

kaddr = kmap_atomic(dest_page);
memcpy(kaddr + pg_offset, workspace->out_buf.dst + buf_offset,
bytes);
kunmap_atomic(kaddr);
memcpy_to_page(dest_page, pg_offset,
workspace->out_buf.dst + buf_offset, bytes);

pg_offset += bytes;
}
Expand Down
56 changes: 56 additions & 0 deletions include/linux/highmem.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,4 +276,60 @@ static inline void copy_highpage(struct page *to, struct page *from)

#endif

static inline void memcpy_page(struct page *dst_page, size_t dst_off,
struct page *src_page, size_t src_off,
size_t len)
{
char *dst = kmap_local_page(dst_page);
char *src = kmap_local_page(src_page);

VM_BUG_ON(dst_off + len > PAGE_SIZE || src_off + len > PAGE_SIZE);
memcpy(dst + dst_off, src + src_off, len);
kunmap_local(src);
kunmap_local(dst);
}

static inline void memmove_page(struct page *dst_page, size_t dst_off,
struct page *src_page, size_t src_off,
size_t len)
{
char *dst = kmap_local_page(dst_page);
char *src = kmap_local_page(src_page);

VM_BUG_ON(dst_off + len > PAGE_SIZE || src_off + len > PAGE_SIZE);
memmove(dst + dst_off, src + src_off, len);
kunmap_local(src);
kunmap_local(dst);
}

static inline void memset_page(struct page *page, size_t offset, int val,
size_t len)
{
char *addr = kmap_local_page(page);

VM_BUG_ON(offset + len > PAGE_SIZE);
memset(addr + offset, val, len);
kunmap_local(addr);
}

static inline void memcpy_from_page(char *to, struct page *page,
size_t offset, size_t len)
{
char *from = kmap_local_page(page);

VM_BUG_ON(offset + len > PAGE_SIZE);
memcpy(to, from + offset, len);
kunmap_local(from);
}

static inline void memcpy_to_page(struct page *page, size_t offset,
const char *from, size_t len)
{
char *to = kmap_local_page(page);

VM_BUG_ON(offset + len > PAGE_SIZE);
memcpy(to + offset, from, len);
kunmap_local(to);
}

#endif /* _LINUX_HIGHMEM_H */
14 changes: 0 additions & 14 deletions lib/iov_iter.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,20 +464,6 @@ void iov_iter_init(struct iov_iter *i, unsigned int direction,
}
EXPORT_SYMBOL(iov_iter_init);

static void memcpy_from_page(char *to, struct page *page, size_t offset, size_t len)
{
char *from = kmap_atomic(page);
memcpy(to, from + offset, len);
kunmap_atomic(from);
}

static void memcpy_to_page(struct page *page, size_t offset, const char *from, size_t len)
{
char *to = kmap_atomic(page);
memcpy(to + offset, from, len);
kunmap_atomic(to);
}

static void memzero_page(struct page *page, size_t offset, size_t len)
{
char *addr = kmap_atomic(page);
Expand Down

0 comments on commit 7a7fd0d

Please sign in to comment.