1 /* 2 * Copyright (C) 2019 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 #include <unordered_map> 25 26 namespace android { 27 namespace dmabufinfo { 28 29 struct DmaBuffer { 30 public: DmaBufferDmaBuffer31 DmaBuffer(ino_t inode, uint64_t size, uint64_t count, const std::string& exporter, 32 const std::string& name) 33 : inode_(inode), size_(size), count_(count), exporter_(exporter), name_(name) { 34 total_refs_ = 0; 35 } 36 ~DmaBuffer() = default; 37 38 // Adds one file descriptor reference for the given pid AddFdRefDmaBuffer39 void AddFdRef(pid_t pid) { 40 AddRefToPidMap(pid, &fdrefs_); 41 total_refs_++; 42 } 43 44 // Adds one map reference for the given pid AddMapRefDmaBuffer45 void AddMapRef(pid_t pid) { 46 AddRefToPidMap(pid, &maprefs_); 47 total_refs_++; 48 } 49 50 // Getters for each property sizeDmaBuffer51 uint64_t size() const { return size_; } fdrefsDmaBuffer52 const std::unordered_map<pid_t, int>& fdrefs() const { return fdrefs_; } maprefsDmaBuffer53 const std::unordered_map<pid_t, int>& maprefs() const { return maprefs_; } inodeDmaBuffer54 ino_t inode() const { return inode_; } total_refsDmaBuffer55 uint64_t total_refs() const { return total_refs_; } countDmaBuffer56 uint64_t count() const { return count_; }; nameDmaBuffer57 const std::string& name() const { return name_; } exporterDmaBuffer58 const std::string& exporter() const { return exporter_; } SetNameDmaBuffer59 void SetName(const std::string& name) { name_ = name; } SetExporterDmaBuffer60 void SetExporter(const std::string& exporter) { exporter_ = exporter; } SetCountDmaBuffer61 void SetCount(uint64_t count) { count_ = count; } 62 63 bool operator==(const DmaBuffer& rhs) { 64 return (inode_ == rhs.inode()) && (size_ == rhs.size()) && (name_ == rhs.name()) && 65 (exporter_ == rhs.exporter()); 66 } 67 68 private: 69 ino_t inode_; 70 uint64_t size_; 71 uint64_t count_; 72 uint64_t total_refs_; 73 std::string exporter_; 74 std::string name_; 75 std::unordered_map<pid_t, int> fdrefs_; 76 std::unordered_map<pid_t, int> maprefs_; AddRefToPidMapDmaBuffer77 void AddRefToPidMap(pid_t pid, std::unordered_map<pid_t, int>* map) { 78 // The first time we find a ref, we set the ref count to 1 79 // otherwise, increment the existing ref count 80 auto [it, inserted] = map->insert(std::make_pair(pid, 1)); 81 if (!inserted) 82 it->second++; 83 } 84 }; 85 86 // Read and return current dma buf objects from 87 // DEBUGFS/dma_buf/bufinfo. The references to each dma buffer are not 88 // populated here and will return an empty vector. 89 // Returns false if something went wrong with the function, true otherwise. 90 bool ReadDmaBufInfo(std::vector<DmaBuffer>* dmabufs, 91 const std::string& path = "/sys/kernel/debug/dma_buf/bufinfo"); 92 93 94 // Read and return dmabuf objects for a given process without the help 95 // of DEBUGFS 96 // Returns false if something went wrong with the function, true otherwise. 97 bool ReadDmaBufInfo(pid_t pid, std::vector<DmaBuffer>* dmabufs); 98 99 // Append new dmabuf objects from a given process to an existing vector. 100 // When the vector contains an existing element with a matching inode, 101 // the reference counts will be updated. 102 // Does not depend on DEBUGFS. 103 // Returns false if something went wrong with the function, true otherwise. 104 bool AppendDmaBufInfo(pid_t pid, std::vector<DmaBuffer>* dmabufs); 105 106 } // namespace dmabufinfo 107 } // namespace android 108