summaryrefslogtreecommitdiffstats
path: root/drivers/fpga/dfl-afu-dma-region.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/fpga/dfl-afu-dma-region.c')
-rw-r--r--drivers/fpga/dfl-afu-dma-region.c53
1 files changed, 4 insertions, 49 deletions
diff --git a/drivers/fpga/dfl-afu-dma-region.c b/drivers/fpga/dfl-afu-dma-region.c
index dcd80b088c7b..62f924489db5 100644
--- a/drivers/fpga/dfl-afu-dma-region.c
+++ b/drivers/fpga/dfl-afu-dma-region.c
@@ -12,6 +12,7 @@
12#include <linux/dma-mapping.h> 12#include <linux/dma-mapping.h>
13#include <linux/sched/signal.h> 13#include <linux/sched/signal.h>
14#include <linux/uaccess.h> 14#include <linux/uaccess.h>
15#include <linux/mm.h>
15 16
16#include "dfl-afu.h" 17#include "dfl-afu.h"
17 18
@@ -32,52 +33,6 @@ void afu_dma_region_init(struct dfl_feature_platform_data *pdata)
32} 33}
33 34
34/** 35/**
35 * afu_dma_adjust_locked_vm - adjust locked memory
36 * @dev: port device
37 * @npages: number of pages
38 * @incr: increase or decrease locked memory
39 *
40 * Increase or decrease the locked memory size with npages input.
41 *
42 * Return 0 on success.
43 * Return -ENOMEM if locked memory size is over the limit and no CAP_IPC_LOCK.
44 */
45static int afu_dma_adjust_locked_vm(struct device *dev, long npages, bool incr)
46{
47 unsigned long locked, lock_limit;
48 int ret = 0;
49
50 /* the task is exiting. */
51 if (!current->mm)
52 return 0;
53
54 down_write(&current->mm->mmap_sem);
55
56 if (incr) {
57 locked = current->mm->locked_vm + npages;
58 lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
59
60 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
61 ret = -ENOMEM;
62 else
63 current->mm->locked_vm += npages;
64 } else {
65 if (WARN_ON_ONCE(npages > current->mm->locked_vm))
66 npages = current->mm->locked_vm;
67 current->mm->locked_vm -= npages;
68 }
69
70 dev_dbg(dev, "[%d] RLIMIT_MEMLOCK %c%ld %ld/%ld%s\n", current->pid,
71 incr ? '+' : '-', npages << PAGE_SHIFT,
72 current->mm->locked_vm << PAGE_SHIFT, rlimit(RLIMIT_MEMLOCK),
73 ret ? "- exceeded" : "");
74
75 up_write(&current->mm->mmap_sem);
76
77 return ret;
78}
79
80/**
81 * afu_dma_pin_pages - pin pages of given dma memory region 36 * afu_dma_pin_pages - pin pages of given dma memory region
82 * @pdata: feature device platform data 37 * @pdata: feature device platform data
83 * @region: dma memory region to be pinned 38 * @region: dma memory region to be pinned
@@ -92,7 +47,7 @@ static int afu_dma_pin_pages(struct dfl_feature_platform_data *pdata,
92 struct device *dev = &pdata->dev->dev; 47 struct device *dev = &pdata->dev->dev;
93 int ret, pinned; 48 int ret, pinned;
94 49
95 ret = afu_dma_adjust_locked_vm(dev, npages, true); 50 ret = account_locked_vm(current->mm, npages, true);
96 if (ret) 51 if (ret)
97 return ret; 52 return ret;
98 53
@@ -121,7 +76,7 @@ put_pages:
121free_pages: 76free_pages:
122 kfree(region->pages); 77 kfree(region->pages);
123unlock_vm: 78unlock_vm:
124 afu_dma_adjust_locked_vm(dev, npages, false); 79 account_locked_vm(current->mm, npages, false);
125 return ret; 80 return ret;
126} 81}
127 82
@@ -141,7 +96,7 @@ static void afu_dma_unpin_pages(struct dfl_feature_platform_data *pdata,
141 96
142 put_all_pages(region->pages, npages); 97 put_all_pages(region->pages, npages);
143 kfree(region->pages); 98 kfree(region->pages);
144 afu_dma_adjust_locked_vm(dev, npages, false); 99 account_locked_vm(current->mm, npages, false);
145 100
146 dev_dbg(dev, "%ld pages unpinned\n", npages); 101 dev_dbg(dev, "%ld pages unpinned\n", npages);
147} 102}