forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/drivers/infiniband/hw/usnic/usnic_uiom.c
....@@ -47,24 +47,10 @@
4747 #include "usnic_uiom.h"
4848 #include "usnic_uiom_interval_tree.h"
4949
50
-static struct workqueue_struct *usnic_uiom_wq;
51
-
5250 #define USNIC_UIOM_PAGE_CHUNK \
5351 ((PAGE_SIZE - offsetof(struct usnic_uiom_chunk, page_list)) /\
5452 ((void *) &((struct usnic_uiom_chunk *) 0)->page_list[1] - \
5553 (void *) &((struct usnic_uiom_chunk *) 0)->page_list[0]))
56
-
57
-static void usnic_uiom_reg_account(struct work_struct *work)
58
-{
59
- struct usnic_uiom_reg *umem = container_of(work,
60
- struct usnic_uiom_reg, work);
61
-
62
- down_write(&umem->mm->mmap_sem);
63
- umem->mm->locked_vm -= umem->diff;
64
- up_write(&umem->mm->mmap_sem);
65
- mmput(umem->mm);
66
- kfree(umem);
67
-}
6854
6955 static int usnic_uiom_dma_fault(struct iommu_domain *domain,
7056 struct device *dev,
....@@ -89,9 +75,7 @@
8975 for_each_sg(chunk->page_list, sg, chunk->nents, i) {
9076 page = sg_page(sg);
9177 pa = sg_phys(sg);
92
- if (!PageDirty(page) && dirty)
93
- set_page_dirty_lock(page);
94
- put_page(page);
78
+ unpin_user_pages_dirty_lock(&page, 1, dirty);
9579 usnic_dbg("pa: %pa\n", &pa);
9680 }
9781 kfree(chunk);
....@@ -99,8 +83,9 @@
9983 }
10084
10185 static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable,
102
- int dmasync, struct list_head *chunk_list)
86
+ int dmasync, struct usnic_uiom_reg *uiomr)
10387 {
88
+ struct list_head *chunk_list = &uiomr->chunk_list;
10489 struct page **page_list;
10590 struct scatterlist *sg;
10691 struct usnic_uiom_chunk *chunk;
....@@ -114,6 +99,7 @@
11499 int flags;
115100 dma_addr_t pa;
116101 unsigned int gup_flags;
102
+ struct mm_struct *mm;
117103
118104 /*
119105 * If the combination of the addr and size requested for this memory
....@@ -136,9 +122,10 @@
136122
137123 npages = PAGE_ALIGN(size + (addr & ~PAGE_MASK)) >> PAGE_SHIFT;
138124
139
- down_write(&current->mm->mmap_sem);
125
+ uiomr->owning_mm = mm = current->mm;
126
+ mmap_read_lock(mm);
140127
141
- locked = npages + current->mm->pinned_vm;
128
+ locked = atomic64_add_return(npages, &current->mm->pinned_vm);
142129 lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
143130
144131 if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) {
....@@ -154,10 +141,11 @@
154141 ret = 0;
155142
156143 while (npages) {
157
- ret = get_user_pages_longterm(cur_base,
158
- min_t(unsigned long, npages,
159
- PAGE_SIZE / sizeof(struct page *)),
160
- gup_flags, page_list, NULL);
144
+ ret = pin_user_pages(cur_base,
145
+ min_t(unsigned long, npages,
146
+ PAGE_SIZE / sizeof(struct page *)),
147
+ gup_flags | FOLL_LONGTERM,
148
+ page_list, NULL);
161149
162150 if (ret < 0)
163151 goto out;
....@@ -166,9 +154,8 @@
166154 off = 0;
167155
168156 while (ret) {
169
- chunk = kmalloc(sizeof(*chunk) +
170
- sizeof(struct scatterlist) *
171
- min_t(int, ret, USNIC_UIOM_PAGE_CHUNK),
157
+ chunk = kmalloc(struct_size(chunk, page_list,
158
+ min_t(int, ret, USNIC_UIOM_PAGE_CHUNK)),
172159 GFP_KERNEL);
173160 if (!chunk) {
174161 ret = -ENOMEM;
....@@ -194,12 +181,13 @@
194181 }
195182
196183 out:
197
- if (ret < 0)
184
+ if (ret < 0) {
198185 usnic_uiom_put_pages(chunk_list, 0);
199
- else
200
- current->mm->pinned_vm = locked;
186
+ atomic64_sub(npages, &current->mm->pinned_vm);
187
+ } else
188
+ mmgrab(uiomr->owning_mm);
201189
202
- up_write(&current->mm->mmap_sem);
190
+ mmap_read_unlock(mm);
203191 free_page((unsigned long) page_list);
204192 return ret;
205193 }
....@@ -293,8 +281,8 @@
293281 size = pa_end - pa_start + PAGE_SIZE;
294282 usnic_dbg("va 0x%lx pa %pa size 0x%zx flags 0x%x",
295283 va_start, &pa_start, size, flags);
296
- err = iommu_map(pd->domain, va_start, pa_start,
297
- size, flags);
284
+ err = iommu_map_atomic(pd->domain, va_start,
285
+ pa_start, size, flags);
298286 if (err) {
299287 usnic_err("Failed to map va 0x%lx pa %pa size 0x%zx with err %d\n",
300288 va_start, &pa_start, size, err);
....@@ -310,8 +298,8 @@
310298 size = pa - pa_start + PAGE_SIZE;
311299 usnic_dbg("va 0x%lx pa %pa size 0x%zx flags 0x%x\n",
312300 va_start, &pa_start, size, flags);
313
- err = iommu_map(pd->domain, va_start, pa_start,
314
- size, flags);
301
+ err = iommu_map_atomic(pd->domain, va_start,
302
+ pa_start, size, flags);
315303 if (err) {
316304 usnic_err("Failed to map va 0x%lx pa %pa size 0x%zx with err %d\n",
317305 va_start, &pa_start, size, err);
....@@ -379,7 +367,7 @@
379367 uiomr->pd = pd;
380368
381369 err = usnic_uiom_get_pages(addr, size, writable, dmasync,
382
- &uiomr->chunk_list);
370
+ uiomr);
383371 if (err) {
384372 usnic_err("Failed get_pages vpn [0x%lx,0x%lx] err %d\n",
385373 vpn_start, vpn_last, err);
....@@ -426,55 +414,29 @@
426414 out_put_pages:
427415 usnic_uiom_put_pages(&uiomr->chunk_list, 0);
428416 spin_unlock(&pd->lock);
417
+ mmdrop(uiomr->owning_mm);
429418 out_free_uiomr:
430419 kfree(uiomr);
431420 return ERR_PTR(err);
432421 }
433422
434
-void usnic_uiom_reg_release(struct usnic_uiom_reg *uiomr,
435
- struct ib_ucontext *ucontext)
423
+static void __usnic_uiom_release_tail(struct usnic_uiom_reg *uiomr)
436424 {
437
- struct task_struct *task;
438
- struct mm_struct *mm;
439
- unsigned long diff;
425
+ mmdrop(uiomr->owning_mm);
426
+ kfree(uiomr);
427
+}
440428
429
+static inline size_t usnic_uiom_num_pages(struct usnic_uiom_reg *uiomr)
430
+{
431
+ return PAGE_ALIGN(uiomr->length + uiomr->offset) >> PAGE_SHIFT;
432
+}
433
+
434
+void usnic_uiom_reg_release(struct usnic_uiom_reg *uiomr)
435
+{
441436 __usnic_uiom_reg_release(uiomr->pd, uiomr, 1);
442437
443
- task = get_pid_task(ucontext->tgid, PIDTYPE_PID);
444
- if (!task)
445
- goto out;
446
- mm = get_task_mm(task);
447
- put_task_struct(task);
448
- if (!mm)
449
- goto out;
450
-
451
- diff = PAGE_ALIGN(uiomr->length + uiomr->offset) >> PAGE_SHIFT;
452
-
453
- /*
454
- * We may be called with the mm's mmap_sem already held. This
455
- * can happen when a userspace munmap() is the call that drops
456
- * the last reference to our file and calls our release
457
- * method. If there are memory regions to destroy, we'll end
458
- * up here and not be able to take the mmap_sem. In that case
459
- * we defer the vm_locked accounting to the system workqueue.
460
- */
461
- if (ucontext->closing) {
462
- if (!down_write_trylock(&mm->mmap_sem)) {
463
- INIT_WORK(&uiomr->work, usnic_uiom_reg_account);
464
- uiomr->mm = mm;
465
- uiomr->diff = diff;
466
-
467
- queue_work(usnic_uiom_wq, &uiomr->work);
468
- return;
469
- }
470
- } else
471
- down_write(&mm->mmap_sem);
472
-
473
- mm->pinned_vm -= diff;
474
- up_write(&mm->mmap_sem);
475
- mmput(mm);
476
-out:
477
- kfree(uiomr);
438
+ atomic64_sub(usnic_uiom_num_pages(uiomr), &uiomr->owning_mm->pinned_vm);
439
+ __usnic_uiom_release_tail(uiomr);
478440 }
479441
480442 struct usnic_uiom_pd *usnic_uiom_alloc_pd(void)
....@@ -602,17 +564,5 @@
602564 return -EPERM;
603565 }
604566
605
- usnic_uiom_wq = create_workqueue(drv_name);
606
- if (!usnic_uiom_wq) {
607
- usnic_err("Unable to alloc wq for drv %s\n", drv_name);
608
- return -ENOMEM;
609
- }
610
-
611567 return 0;
612
-}
613
-
614
-void usnic_uiom_fini(void)
615
-{
616
- flush_workqueue(usnic_uiom_wq);
617
- destroy_workqueue(usnic_uiom_wq);
618568 }