2020-11-24 06:14:18

by Ira Weiny

[permalink] [raw]
Subject: [PATCH 00/17] kmap: Create mem*_page interfaces

From: Ira Weiny <[email protected]>

The following pattern is used often:

kmap()
memcpy(), memmove(), or memset()
kunmap()

The problem with this is 2 fold: 1) This is best done with k[un]map_atomic().
2) kmap() is expanding and evolving beyond the use of highmem.

To the second point we have new functionality being placed behind kmap, such as
PKS, which has nothing to do with highmem. Also we have new kmap interfaces,
kmap_local() which allow for a more fined grained mapping of pages and would be
very appropriate for the above pattern.

iov_iter.c already defined 3 functions which do most of what we want.

memcpy_from_page()
memcpy_to_page()
memzero_page()

Lift these to the core and enhance with memcpy_page(), memmove_page(), and
memset_page(). Then replace the patterns throughout the kernel as appropriate.

Once the kmap_local() implementation is finalized the kmap_atomic() can be
replaced with kmap_local(). For the moment use kmap_atomic().


Ira Weiny (17):
mm/highmem: Lift memcpy_[to|from]_page and memset_page to core
drivers/firmware_loader: Use new memcpy_[to|from]_page()
drivers/gpu: Convert to mem*_page()
fs/afs: Convert to memzero_page()
fs/btrfs: Convert to memzero_page()
fs/hfs: Convert to mem*_page() interface
fs/cifs: Convert to memcpy_page()
fs/hfsplus: Convert to mem*_page()
fs/f2fs: Remove f2fs_copy_page()
fs/freevxfs: Use memcpy_to_page()
fs/reiserfs: Use memcpy_from_page()
fs/cramfs: Use memcpy_from_page()
drivers/target: Convert to mem*_page()
drivers/scsi: Use memcpy_to_page()
drivers/staging: Use memcpy_to/from_page()
lib: Use mempcy_to/from_page()
samples: Use memcpy_to/from_page()

drivers/base/firmware_loader/fallback.c | 11 +++--
drivers/gpu/drm/gma500/gma_display.c | 7 ++-
drivers/gpu/drm/gma500/mmu.c | 4 +-
drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 6 +--
drivers/gpu/drm/i915/gt/intel_gtt.c | 9 +---
drivers/gpu/drm/i915/gt/shmem_utils.c | 8 ++--
drivers/scsi/ipr.c | 11 +----
drivers/staging/rts5208/rtsx_transport.c | 8 ++--
drivers/target/target_core_rd.c | 6 +--
drivers/target/target_core_transport.c | 10 ++---
fs/afs/write.c | 5 +--
fs/btrfs/inode.c | 21 +++------
fs/cifs/smb2ops.c | 10 ++---
fs/cramfs/inode.c | 3 +-
fs/f2fs/f2fs.h | 10 -----
fs/f2fs/file.c | 3 +-
fs/freevxfs/vxfs_immed.c | 6 +--
fs/hfs/bnode.c | 13 ++----
fs/hfsplus/bnode.c | 53 +++++++----------------
fs/reiserfs/journal.c | 9 ++--
include/linux/pagemap.h | 49 +++++++++++++++++++++
lib/iov_iter.c | 21 ---------
lib/test_bpf.c | 11 +----
lib/test_hmm.c | 10 +----
samples/vfio-mdev/mbochs.c | 8 ++--
25 files changed, 119 insertions(+), 193 deletions(-)

--
2.28.0.rc0.12.gb6a658bd00c9


2020-11-24 19:49:28

by Ira Weiny

[permalink] [raw]
Subject: [PATCH 06/17] fs/hfs: Convert to mem*_page() interface

From: Ira Weiny <[email protected]>

Where possible remove kmap/mem*/kunmap in favor of the new mem*_page()
calls.

Signed-off-by: Ira Weiny <[email protected]>
---
fs/hfs/bnode.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c
index b63a4df7327b..56037ae5ba69 100644
--- a/fs/hfs/bnode.c
+++ b/fs/hfs/bnode.c
@@ -23,8 +23,7 @@ void hfs_bnode_read(struct hfs_bnode *node, void *buf,
off += node->page_offset;
page = node->page[0];

- memcpy(buf, kmap(page) + off, len);
- kunmap(page);
+ memcpy_from_page(buf, page, off, len);
}

u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off)
@@ -65,8 +64,7 @@ void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len)
off += node->page_offset;
page = node->page[0];

- memcpy(kmap(page) + off, buf, len);
- kunmap(page);
+ memcpy_to_page(page, off, buf, len);
set_page_dirty(page);
}

@@ -90,8 +88,7 @@ void hfs_bnode_clear(struct hfs_bnode *node, int off, int len)
off += node->page_offset;
page = node->page[0];

- memset(kmap(page) + off, 0, len);
- kunmap(page);
+ memzero_page(page, off, len);
set_page_dirty(page);
}

@@ -108,9 +105,7 @@ void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst,
src_page = src_node->page[0];
dst_page = dst_node->page[0];

- memcpy(kmap(dst_page) + dst, kmap(src_page) + src, len);
- kunmap(src_page);
- kunmap(dst_page);
+ memcpy_page(dst_page, dst, src_page, src, len);
set_page_dirty(dst_page);
}

--
2.28.0.rc0.12.gb6a658bd00c9

2020-11-25 01:50:29

by Ira Weiny

[permalink] [raw]
Subject: [PATCH 02/17] drivers/firmware_loader: Use new memcpy_[to|from]_page()

From: Ira Weiny <[email protected]>

Too many users are using kmap_*() incorrectly and a common pattern is
for them to kmap/mempcy/kunmap. Change these calls to use the newly
lifted memcpy_[to|from]_page() calls.

Cc: Luis Chamberlain <[email protected]>
Signed-off-by: Ira Weiny <[email protected]>
---
drivers/base/firmware_loader/fallback.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c
index 4dec4b79ae06..dc93dc307d18 100644
--- a/drivers/base/firmware_loader/fallback.c
+++ b/drivers/base/firmware_loader/fallback.c
@@ -10,6 +10,7 @@
#include <linux/sysctl.h>
#include <linux/vmalloc.h>
#include <linux/module.h>
+#include <linux/pagemap.h>

#include "fallback.h"
#include "firmware.h"
@@ -317,19 +318,17 @@ static void firmware_rw(struct fw_priv *fw_priv, char *buffer,
loff_t offset, size_t count, bool read)
{
while (count) {
- void *page_data;
int page_nr = offset >> PAGE_SHIFT;
int page_ofs = offset & (PAGE_SIZE-1);
int page_cnt = min_t(size_t, PAGE_SIZE - page_ofs, count);

- page_data = kmap(fw_priv->pages[page_nr]);
-
if (read)
- memcpy(buffer, page_data + page_ofs, page_cnt);
+ memcpy_from_page(buffer, fw_priv->pages[page_nr],
+ page_ofs, page_cnt);
else
- memcpy(page_data + page_ofs, buffer, page_cnt);
+ memcpy_to_page(fw_priv->pages[page_nr], page_ofs,
+ buffer, page_cnt);

- kunmap(fw_priv->pages[page_nr]);
buffer += page_cnt;
offset += page_cnt;
count -= page_cnt;
--
2.28.0.rc0.12.gb6a658bd00c9