Merge "meminfo: handle multiple buffer references in dmabufinfo"

This commit is contained in:
Treehugger Robot 2019-01-30 19:11:20 +00:00 committed by Gerrit Code Review
commit 627a37cad9
3 changed files with 58 additions and 16 deletions

View file

@ -119,9 +119,23 @@ static bool ReadDmaBufFdRefs(pid_t pid, std::vector<DmaBuffer>* dmabufs) {
return false;
}
DmaBuffer& buf =
uint64_t inode = sb.st_ino;
auto buf = std::find_if(dmabufs->begin(), dmabufs->end(),
[&inode](const DmaBuffer& dbuf) { return dbuf.inode() == inode; });
if (buf != dmabufs->end()) {
if (buf->name() == "" || buf->name() == "<unknown>")
buf->SetName(name);
if (buf->exporter() == "" || buf->exporter() == "<unknown>")
buf->SetExporter(exporter);
if (buf->count() == 0)
buf->SetCount(count);
buf->AddFdRef(pid);
return true;
}
DmaBuffer& db =
dmabufs->emplace_back(sb.st_ino, sb.st_blocks * 512, count, exporter, name);
buf.AddFdRef(pid);
db.AddFdRef(pid);
}
return true;
@ -225,6 +239,10 @@ bool ReadDmaBufInfo(std::vector<DmaBuffer>* dmabufs, const std::string& path) {
bool ReadDmaBufInfo(pid_t pid, std::vector<DmaBuffer>* dmabufs) {
dmabufs->clear();
return AppendDmaBufInfo(pid, dmabufs);
}
bool AppendDmaBufInfo(pid_t pid, std::vector<DmaBuffer>* dmabufs) {
if (!ReadDmaBufFdRefs(pid, dmabufs)) {
LOG(ERROR) << "Failed to read dmabuf fd references";
return false;

View file

@ -21,6 +21,7 @@
#include <string>
#include <vector>
#include <unordered_map>
#include <android-base/file.h>
#include <android-base/logging.h>
@ -61,18 +62,16 @@ struct ion_heap_data {
#define EXPECT_PID_IN_FDREFS(_bufptr, _pid, _expect) \
do { \
const std::vector<pid_t>& _fdrefs = _bufptr->fdrefs(); \
auto _ref = std::find_if(_fdrefs.begin(), _fdrefs.end(), \
[&](const pid_t& p) { return p == _pid; }); \
EXPECT_EQ((_ref == _fdrefs.end()), _expect); \
const std::unordered_map<pid_t, int>& _fdrefs = _bufptr->fdrefs(); \
auto _ref = _fdrefs.find(_pid); \
EXPECT_EQ((_ref != _fdrefs.end()), _expect); \
} while (0)
#define EXPECT_PID_IN_MAPREFS(_bufptr, _pid, _expect) \
do { \
const std::vector<pid_t>& _maprefs = _bufptr->maprefs(); \
auto _ref = std::find_if(_maprefs.begin(), _maprefs.end(), \
[&](const pid_t& p) { return p == _pid; }); \
EXPECT_EQ((_ref == _maprefs.end()), _expect); \
const std::unordered_map<pid_t, int>& _maprefs = _bufptr->maprefs(); \
auto _ref = _maprefs.find(_pid); \
EXPECT_EQ((_ref != _maprefs.end()), _expect); \
} while (0)
TEST(DmaBufInfoParser, TestReadDmaBufInfo) {

View file

@ -21,6 +21,7 @@
#include <string>
#include <vector>
#include <unordered_map>
namespace android {
namespace dmabufinfo {
@ -33,20 +34,27 @@ struct DmaBuffer {
~DmaBuffer() = default;
// Adds one file descriptor reference for the given pid
void AddFdRef(pid_t pid) { fdrefs_.emplace_back(pid); }
void AddFdRef(pid_t pid) {
AddRefToPidMap(pid, &fdrefs_);
}
// Adds one map reference for the given pid
void AddMapRef(pid_t pid) { maprefs_.emplace_back(pid); }
void AddMapRef(pid_t pid) {
AddRefToPidMap(pid, &maprefs_);
}
// Getters for each property
uint64_t size() { return size_; }
const std::vector<pid_t>& fdrefs() const { return fdrefs_; }
const std::vector<pid_t>& maprefs() const { return maprefs_; }
const std::unordered_map<pid_t, int>& fdrefs() const { return fdrefs_; }
const std::unordered_map<pid_t, int>& maprefs() const { return maprefs_; }
ino_t inode() const { return inode_; }
uint64_t total_refs() const { return fdrefs_.size() + maprefs_.size(); }
uint64_t count() const { return count_; };
const std::string& name() const { return name_; }
const std::string& exporter() const { return exporter_; }
void SetName(const std::string& name) { name_ = name; }
void SetExporter(const std::string& exporter) { exporter_ = exporter; }
void SetCount(uint64_t count) { count_ = count; }
private:
ino_t inode_;
@ -54,20 +62,37 @@ struct DmaBuffer {
uint64_t count_;
std::string exporter_;
std::string name_;
std::vector<pid_t> fdrefs_;
std::vector<pid_t> maprefs_;
std::unordered_map<pid_t, int> fdrefs_;
std::unordered_map<pid_t, int> maprefs_;
void AddRefToPidMap(pid_t pid, std::unordered_map<pid_t, int>* map) {
// The first time we find a ref, we set the ref count to 1
// otherwise, increment the existing ref count
auto [it, inserted] = map->insert(std::make_pair(pid, 1));
if (!inserted)
it->second++;
}
};
// Read and return current dma buf objects from
// DEBUGFS/dma_buf/bufinfo. The references to each dma buffer are not
// populated here and will return an empty vector.
//
// Returns false if something went wrong with the function, true otherwise.
bool ReadDmaBufInfo(std::vector<DmaBuffer>* dmabufs,
const std::string& path = "/sys/kernel/debug/dma_buf/bufinfo");
// Read and return dmabuf objects for a given process without the help
// of DEBUGFS
//
// Returns false if something went wrong with the function, true otherwise.
bool ReadDmaBufInfo(pid_t pid, std::vector<DmaBuffer>* dmabufs);
// Append dmabuf objects for a given process without the help
// of DEBUGFS to an existing vector
//
// Returns false if something went wrong with the function, true otherwise.
bool AppendDmaBufInfo(pid_t pid, std::vector<DmaBuffer>* dmabufs);
} // namespace dmabufinfo
} // namespace android