Merge branch 'kmap-conversion-for-5.12' of git://git.kernel.org/pub/scm/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/cover.1614090658.git.dsterba@suse.com/ 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
This commit is contained in:
commit
7a7fd0de4a
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
@ -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++;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue