]> Git Repo - J-linux.git/blob - include/linux/pgalloc_tag.h
Merge remote-tracking branch 'drm/drm-fixes' into drm-misc-fixes
[J-linux.git] / include / linux / pgalloc_tag.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * page allocation tagging
4  */
5 #ifndef _LINUX_PGALLOC_TAG_H
6 #define _LINUX_PGALLOC_TAG_H
7
8 #include <linux/alloc_tag.h>
9
10 #ifdef CONFIG_MEM_ALLOC_PROFILING
11
12 #include <linux/page_ext.h>
13
14 extern struct page_ext_operations page_alloc_tagging_ops;
15
16 static inline union codetag_ref *codetag_ref_from_page_ext(struct page_ext *page_ext)
17 {
18         return (void *)page_ext + page_alloc_tagging_ops.offset;
19 }
20
21 static inline struct page_ext *page_ext_from_codetag_ref(union codetag_ref *ref)
22 {
23         return (void *)ref - page_alloc_tagging_ops.offset;
24 }
25
26 /* Should be called only if mem_alloc_profiling_enabled() */
27 static inline union codetag_ref *get_page_tag_ref(struct page *page)
28 {
29         if (page) {
30                 struct page_ext *page_ext = page_ext_get(page);
31
32                 if (page_ext)
33                         return codetag_ref_from_page_ext(page_ext);
34         }
35         return NULL;
36 }
37
38 static inline void put_page_tag_ref(union codetag_ref *ref)
39 {
40         page_ext_put(page_ext_from_codetag_ref(ref));
41 }
42
43 static inline void pgalloc_tag_add(struct page *page, struct task_struct *task,
44                                    unsigned int nr)
45 {
46         if (mem_alloc_profiling_enabled()) {
47                 union codetag_ref *ref = get_page_tag_ref(page);
48
49                 if (ref) {
50                         alloc_tag_add(ref, task->alloc_tag, PAGE_SIZE * nr);
51                         put_page_tag_ref(ref);
52                 }
53         }
54 }
55
56 static inline void pgalloc_tag_sub(struct page *page, unsigned int nr)
57 {
58         if (mem_alloc_profiling_enabled()) {
59                 union codetag_ref *ref = get_page_tag_ref(page);
60
61                 if (ref) {
62                         alloc_tag_sub(ref, PAGE_SIZE * nr);
63                         put_page_tag_ref(ref);
64                 }
65         }
66 }
67
68 static inline void pgalloc_tag_split(struct page *page, unsigned int nr)
69 {
70         int i;
71         struct page_ext *page_ext;
72         union codetag_ref *ref;
73         struct alloc_tag *tag;
74
75         if (!mem_alloc_profiling_enabled())
76                 return;
77
78         page_ext = page_ext_get(page);
79         if (unlikely(!page_ext))
80                 return;
81
82         ref = codetag_ref_from_page_ext(page_ext);
83         if (!ref->ct)
84                 goto out;
85
86         tag = ct_to_alloc_tag(ref->ct);
87         page_ext = page_ext_next(page_ext);
88         for (i = 1; i < nr; i++) {
89                 /* Set new reference to point to the original tag */
90                 alloc_tag_ref_set(codetag_ref_from_page_ext(page_ext), tag);
91                 page_ext = page_ext_next(page_ext);
92         }
93 out:
94         page_ext_put(page_ext);
95 }
96
97 static inline struct alloc_tag *pgalloc_tag_get(struct page *page)
98 {
99         struct alloc_tag *tag = NULL;
100
101         if (mem_alloc_profiling_enabled()) {
102                 union codetag_ref *ref = get_page_tag_ref(page);
103
104                 alloc_tag_sub_check(ref);
105                 if (ref && ref->ct)
106                         tag = ct_to_alloc_tag(ref->ct);
107                 put_page_tag_ref(ref);
108         }
109
110         return tag;
111 }
112
113 static inline void pgalloc_tag_sub_pages(struct alloc_tag *tag, unsigned int nr)
114 {
115         if (mem_alloc_profiling_enabled() && tag)
116                 this_cpu_sub(tag->counters->bytes, PAGE_SIZE * nr);
117 }
118
119 #else /* CONFIG_MEM_ALLOC_PROFILING */
120
121 static inline union codetag_ref *get_page_tag_ref(struct page *page) { return NULL; }
122 static inline void put_page_tag_ref(union codetag_ref *ref) {}
123 static inline void pgalloc_tag_add(struct page *page, struct task_struct *task,
124                                    unsigned int nr) {}
125 static inline void pgalloc_tag_sub(struct page *page, unsigned int nr) {}
126 static inline void pgalloc_tag_split(struct page *page, unsigned int nr) {}
127 static inline struct alloc_tag *pgalloc_tag_get(struct page *page) { return NULL; }
128 static inline void pgalloc_tag_sub_pages(struct alloc_tag *tag, unsigned int nr) {}
129
130 #endif /* CONFIG_MEM_ALLOC_PROFILING */
131
132 #endif /* _LINUX_PGALLOC_TAG_H */
This page took 0.034851 seconds and 4 git commands to generate.