@@ -29,33 +29,52 @@ MODULE_PARM_DESC(cache_size, "Send and receive side cache size limit (in MB)");
29
29
bool hfi1_can_pin_pages (struct hfi1_devdata * dd , struct mm_struct * mm ,
30
30
u32 nlocked , u32 npages )
31
31
{
32
- unsigned long ulimit = rlimit (RLIMIT_MEMLOCK ), pinned , cache_limit ,
33
- size = (cache_size * (1UL << 20 )); /* convert to bytes */
34
- unsigned int usr_ctxts =
35
- dd -> num_rcv_contexts - dd -> first_dyn_alloc_ctxt ;
36
- bool can_lock = capable (CAP_IPC_LOCK );
32
+ unsigned long ulimit_pages ;
33
+ unsigned long cache_limit_pages ;
34
+ unsigned int usr_ctxts ;
37
35
38
36
/*
39
- * Calculate per-cache size. The calculation below uses only a quarter
40
- * of the available per-context limit. This leaves space for other
41
- * pinning. Should we worry about shared ctxts?
37
+ * Perform RLIMIT_MEMLOCK based checks unless CAP_IPC_LOCK is present.
42
38
*/
43
- cache_limit = (ulimit / usr_ctxts ) / 4 ;
44
-
45
- /* If ulimit isn't set to "unlimited" and is smaller than cache_size. */
46
- if (ulimit != (-1UL ) && size > cache_limit )
47
- size = cache_limit ;
48
-
49
- /* Convert to number of pages */
50
- size = DIV_ROUND_UP (size , PAGE_SIZE );
51
-
52
- pinned = atomic64_read (& mm -> pinned_vm );
39
+ if (!capable (CAP_IPC_LOCK )) {
40
+ ulimit_pages =
41
+ DIV_ROUND_DOWN_ULL (rlimit (RLIMIT_MEMLOCK ), PAGE_SIZE );
42
+
43
+ /*
44
+ * Pinning these pages would exceed this process's locked memory
45
+ * limit.
46
+ */
47
+ if (atomic64_read (& mm -> pinned_vm ) + npages > ulimit_pages )
48
+ return false;
49
+
50
+ /*
51
+ * Only allow 1/4 of the user's RLIMIT_MEMLOCK to be used for HFI
52
+ * caches. This fraction is then equally distributed among all
53
+ * existing user contexts. Note that if RLIMIT_MEMLOCK is
54
+ * 'unlimited' (-1), the value of this limit will be > 2^42 pages
55
+ * (2^64 / 2^12 / 2^8 / 2^2).
56
+ *
57
+ * The effectiveness of this check may be reduced if I/O occurs on
58
+ * some user contexts before all user contexts are created. This
59
+ * check assumes that this process is the only one using this
60
+ * context (e.g., the corresponding fd was not passed to another
61
+ * process for concurrent access) as there is no per-context,
62
+ * per-process tracking of pinned pages. It also assumes that each
63
+ * user context has only one cache to limit.
64
+ */
65
+ usr_ctxts = dd -> num_rcv_contexts - dd -> first_dyn_alloc_ctxt ;
66
+ if (nlocked + npages > (ulimit_pages / usr_ctxts / 4 ))
67
+ return false;
68
+ }
53
69
54
- /* First, check the absolute limit against all pinned pages. */
55
- if (pinned + npages >= ulimit && !can_lock )
70
+ /*
71
+ * Pinning these pages would exceed the size limit for this cache.
72
+ */
73
+ cache_limit_pages = cache_size * (1024 * 1024 ) / PAGE_SIZE ;
74
+ if (nlocked + npages > cache_limit_pages )
56
75
return false;
57
76
58
- return (( nlocked + npages ) <= size ) || can_lock ;
77
+ return true ;
59
78
}
60
79
61
80
int hfi1_acquire_user_pages (struct mm_struct * mm , unsigned long vaddr , size_t npages ,
0 commit comments