1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <sys/types.h>
20 #include <unistd.h>
21 
22 #include <string>
23 #include <vector>
24 
25 #include <android-base/unique_fd.h>
26 
27 namespace android {
28 namespace meminfo {
29 
30 class PageAcct final {
31     // Class for per-page accounting by using kernel provided interfaces like
32     // kpagecount, kpageflags etc.
33   public:
KernelHasPageIdle()34     static bool KernelHasPageIdle() {
35         return (access("/sys/kernel/mm/page_idle/bitmap", R_OK | W_OK) == 0);
36     }
37 
38     bool InitPageAcct(bool pageidle_enable = false);
39     bool PageFlags(uint64_t pfn, uint64_t* flags);
40     bool PageMapCount(uint64_t pfn, uint64_t* mapcount);
41 
42     int IsPageIdle(uint64_t pfn);
43 
44     // The only way to create PageAcct object
Instance()45     static PageAcct& Instance() {
46         static PageAcct instance;
47         return instance;
48     }
49 
50     ~PageAcct() = default;
51 
52   private:
PageAcct()53     PageAcct() : kpagecount_fd_(-1), kpageflags_fd_(-1), pageidle_fd_(-1) {}
54     int MarkPageIdle(uint64_t pfn) const;
55     int GetPageIdle(uint64_t pfn) const;
56 
57     // Non-copyable & Non-movable
58     PageAcct(const PageAcct&) = delete;
59     PageAcct& operator=(const PageAcct&) = delete;
60     PageAcct& operator=(PageAcct&&) = delete;
61     PageAcct(PageAcct&&) = delete;
62 
63     ::android::base::unique_fd kpagecount_fd_;
64     ::android::base::unique_fd kpageflags_fd_;
65     ::android::base::unique_fd pageidle_fd_;
66 };
67 
68 // Returns if the page present bit is set in the value
69 // passed in.
70 bool page_present(uint64_t pagemap_val);
71 
72 // Returns if the page swapped bit is set in the value
73 // passed in.
74 bool page_swapped(uint64_t pagemap_val);
75 
76 // Returns the page frame number (physical page) from
77 // pagemap value
78 uint64_t page_pfn(uint64_t pagemap_val);
79 
80 }  // namespace meminfo
81 }  // namespace android
82