summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinchan Kim <minchan@google.com>2020-12-28 17:50:17 -0800
committerMinchan Kim <minchan@google.com>2021-01-05 08:01:46 -0800
commit411a6d8e49545ea18b1c2734de51d103d25b4d52 (patch)
treed1937b337a1b0d8d6a2e284960adc2c2776bee3c
parentc31b9b8adffe9f2f96bdabedf61e596a7e41193e (diff)
downloadabrolhos-411a6d8e49545ea18b1c2734de51d103d25b4d52.tar.gz
edgetpu: use pin_userpages_fast
CMA allocation fails since edgetpu driver holds a referece count for anonymous pages. To fix it, use pin_user_pages friends which will migrate the pinned page out of CMA area when the API is called so CMA area will not have pinned pages so that CMA allocation will be succeeded. [ 249.734855][ T2771] page:00000000791d5a0c refcount:2 mapcount:1 mapping:0000000000000000 index:0x76bb2ba pfn:0x9c28d8 [ 249.745238][ T2771] anon flags: 0x8000000000080016(referenced|uptodate|lru|swapbacked) [ 249.753139][ T2771] raw: 8000000000080016 ffffffff250c5448 ffffffff24eb5148 ffffff8910b9a121 [ 249.761562][ T2771] raw: 00000000076bb2ba 0000000000000000 0000000200000000 ffffff891f6ae000 [ 249.769961][ T2771] page dumped because: fail to isolate [ 249.775282][ T2771] page->mem_cgroup:ffffff891f6ae000 [ 249.780320][ T2771] page_owner tracks the page as allocated [ 249.785877][ T2771] page last allocated via order 0, migratetype Movable, gfp_mask 0x100dca(GFP_HIGHUSER_MOVABLE|__GFP_ZERO) [ 249.797082][ T2771] prep_new_page+0x54/0x1c4 [ 249.801421][ T2771] get_page_from_freelist+0x278/0x2bc [ 249.806632][ T2771] __alloc_pages_nodemask+0x140/0x2c0 [ 249.811818][ T2771] do_anonymous_page+0xd0/0x3f0 [ 249.816531][ T2771] handle_pte_fault+0x100/0x29c [ 249.821220][ T2771] handle_mm_fault+0x1a4/0x2d4 [ 249.825822][ T2771] __get_user_pages+0x178/0x3e4 [ 249.830487][ T2771] get_user_pages_unlocked+0xbc/0x280 [ 249.835694][ T2771] internal_get_user_pages_fast+0x20c/0x2c8 [ 249.841454][ T2771] get_user_pages_fast+0x18/0x30 [ 249.846246][ T2771] edgetpu_pin_user_pages+0x50/0x10c [abrolhos] [ 249.852314][ T2771] edgetpu_device_group_map+0x4c/0x2c0 [abrolhos] [ 249.858566][ T2771] edgetpu_ioctl_map_buffer+0x16c/0x2a4 [abrolhos] [ 249.864905][ T2771] edgetpu_ioctl+0x490/0x864 [abrolhos] [ 249.870289][ T2771] edgetpu_fs_ioctl+0x2c/0x38 [abrolhos] Bug: 176462375 Signed-off-by: Minchan Kim <minchan@google.com> Change-Id: I57413553b81708ff0e1e25866d0c9643274670f0
-rw-r--r--drivers/edgetpu/edgetpu-device-group.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/edgetpu/edgetpu-device-group.c b/drivers/edgetpu/edgetpu-device-group.c
index 08a97a2..f9d681e 100644
--- a/drivers/edgetpu/edgetpu-device-group.c
+++ b/drivers/edgetpu/edgetpu-device-group.c
@@ -919,7 +919,7 @@ static void edgetpu_unmap_node(struct edgetpu_mapping *map)
map->dir == DMA_BIDIRECTIONAL)
set_page_dirty(page);
- put_page(page);
+ unpin_user_page(page);
}
sg_free_table(&map->sgt);
@@ -991,7 +991,8 @@ static struct page **edgetpu_pin_user_pages(struct edgetpu_device_group *group,
/*
* DMA Buffers appear to be always dirty, so mark pages as always writeable
*/
- ret = get_user_pages_fast(host_addr & PAGE_MASK, num_pages, 1, pages);
+ ret = pin_user_pages_fast(host_addr & PAGE_MASK, num_pages,
+ FOLL_WRITE | FOLL_LONGTERM, pages);
if (ret < 0) {
etdev_dbg(etdev, "get user pages failed %u:%pK-%u: %d",
group->workload_id, (void *)host_addr, num_pages,
@@ -1015,7 +1016,7 @@ static struct page **edgetpu_pin_user_pages(struct edgetpu_device_group *group,
error:
for (i = 0; i < num_pages; i++)
- put_page(pages[i]);
+ unpin_user_page(pages[i]);
kfree(pages);
return ERR_PTR(ret);
@@ -1093,7 +1094,7 @@ error_free_sgt:
}
error:
for (i = 0; i < num_pages; i++)
- put_page(pages[i]);
+ unpin_user_page(pages[i]);
if (hmap) {
edgetpu_device_group_put(hmap->map.priv);
kfree(hmap->sg_tables);