1 /* 2 * Copyright (C) 2023 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 <memory> 20 #include <vector> 21 22 #include <stddef.h> 23 24 #include <memevents/bpf_types.h> 25 26 namespace android { 27 namespace bpf { 28 namespace memevents { 29 30 enum MemEventClient { 31 // BASE should always be first, used for lower-bound checks 32 BASE = 0, 33 AMS = BASE, 34 LMKD, 35 /* 36 * Flag to indicate whether this `MemEventListener` instance is used for 37 * testing purposes. This allows us to skip internal calls that would 38 * otherwise interfere with test setup, and mocks for BPF ring buffer, 39 * and BPF program behavior. 40 */ 41 TEST_CLIENT, 42 // NR_CLIENTS should always come after the last valid client 43 NR_CLIENTS 44 }; 45 46 class MemBpfRingbuf; 47 48 class MemEventListener final { 49 public: 50 /* 51 * MemEventListener will `std::abort` when failing to initialize 52 * the bpf ring buffer manager, on a bpf-rb supported kernel. 53 * 54 * If running on a kernel that doesn't support bpf-rb, the listener 55 * will initialize in an invalid state, preventing it from making 56 * any actions/calls. 57 * To check if the listener initialized correctly use `ok()`. 58 */ 59 MemEventListener(MemEventClient client, bool attachTpForTests = false); 60 ~MemEventListener(); 61 62 /** 63 * Check if the listener was initialized correctly, with a valid bpf 64 * ring buffer manager on a bpf-rb supported kernel. 65 * 66 * @return true if initialized with a valid bpf rb manager, false 67 * otherwise. 68 */ 69 bool ok(); 70 71 /** 72 * Registers the requested memory event to the listener. 73 * 74 * @param event_type Memory event type to listen for. 75 * @return true if registration was successful, false otherwise. 76 */ 77 bool registerEvent(mem_event_type_t event_type); 78 79 /** 80 * Waits for a [registered] memory event notification. 81 * 82 * `listen()` will block until either: 83 * - Receives a registered memory event 84 * - Timeout expires 85 * 86 * Note that the default timeout (-1) causes `listen()` to block 87 * indefinitely. 88 * 89 * @param timeout_ms number of milliseconds that listen will block. 90 * @return true if there are new memory events to read, false otherwise. 91 */ 92 bool listen(int timeout_ms = -1); 93 94 /** 95 * Stops listening for a specific memory event type. 96 * 97 * @param event_type Memory event type to stop listening to. 98 * @return true if unregistering was successful, false otherwise 99 */ 100 bool deregisterEvent(mem_event_type_t event_type); 101 102 /** 103 * Closes all the events' file descriptors and `mEpfd`. This will also 104 * gracefully terminate any ongoing `listen()`. 105 */ 106 void deregisterAllEvents(); 107 108 /** 109 * Retrieves unread [registered] memory events, and stores them into the 110 * provided `mem_events` vector. 111 * 112 * On first invocation, it will read/store all memory events. After the 113 * initial invocation, it will only read/store new, unread, events. 114 * 115 * @param mem_events vector in which we want to append the read 116 * memory events. 117 * @return true on success, false on failure. 118 */ 119 bool getMemEvents(std::vector<mem_event_t>& mem_events); 120 121 /** 122 * Expose the MemEventClient's ring-buffer file descriptor for polling purposes, 123 * not intended for consumption. To consume use `ConsumeAll()`. 124 * 125 * @return file descriptor (non negative integer), -1 on error. 126 */ 127 int getRingBufferFd(); 128 129 private: 130 bool mEventsRegistered[NR_MEM_EVENTS]; 131 int mNumEventsRegistered; 132 MemEventClient mClient; 133 std::unique_ptr<MemBpfRingbuf> memBpfRb; 134 bool mAttachTpForTests; 135 136 bool isValidEventType(mem_event_type_t event_type) const; 137 }; 138 139 } // namespace memevents 140 } // namespace bpf 141 } // namespace android 142