mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1038888
- Extend system memory reporter to report ion memory. r=njn
--HG-- extra : rebase_source : 39dbc0a696d67c1a239876ec8ca412527fc2712e
This commit is contained in:
parent
1679b15cf6
commit
2304c179f5
@ -46,6 +46,26 @@ namespace SystemMemoryReporter {
|
||||
#error "This won't work if we're not on Linux."
|
||||
#endif
|
||||
|
||||
/**
|
||||
* RAII helper that will close an open DIR handle.
|
||||
*/
|
||||
struct MOZ_STACK_CLASS AutoDir
|
||||
{
|
||||
AutoDir(DIR* aDir) : mDir(aDir) {}
|
||||
~AutoDir() { if (mDir) closedir(mDir); };
|
||||
DIR* mDir;
|
||||
};
|
||||
|
||||
/**
|
||||
* RAII helper that will close an open FILE handle.
|
||||
*/
|
||||
struct MOZ_STACK_CLASS AutoFile
|
||||
{
|
||||
AutoFile(FILE* aFile) : mFile(aFile) {}
|
||||
~AutoFile() { if (mFile) fclose(mFile); }
|
||||
FILE* mFile;
|
||||
};
|
||||
|
||||
static bool
|
||||
EndsWithLiteral(const nsCString& aHaystack, const char* aNeedle)
|
||||
{
|
||||
@ -180,6 +200,10 @@ public:
|
||||
rv = CollectKgslReports(aHandleReport, aData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Report ION memory usage.
|
||||
rv = CollectIonReports(aHandleReport, aData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -680,6 +704,106 @@ private:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
CollectIonReports(nsIHandleReportCallback* aHandleReport,
|
||||
nsISupports* aData)
|
||||
{
|
||||
// ION is a replacement for PMEM (and other similar allocators).
|
||||
//
|
||||
// More details from http://lwn.net/Articles/480055/
|
||||
// "Like its PMEM-like predecessors, ION manages one or more memory pools,
|
||||
// some of which are set aside at boot time to combat fragmentation or to
|
||||
// serve special hardware needs. GPUs, display controllers, and cameras
|
||||
// are some of the hardware blocks that may have special memory
|
||||
// requirements."
|
||||
//
|
||||
// The file format starts as follows:
|
||||
// client pid size
|
||||
// ----------------------------------------------------
|
||||
// adsprpc-smd 1 4096
|
||||
// fd900000.qcom,mdss_mdp 1 1658880
|
||||
// ----------------------------------------------------
|
||||
// orphaned allocations (info is from last known client):
|
||||
// Homescreen 24100 294912 0 1
|
||||
// b2g 23987 1658880 0 1
|
||||
// mdss_fb0 401 1658880 0 1
|
||||
// b2g 23987 4096 0 1
|
||||
// Built-in Keyboa 24205 61440 0 1
|
||||
// ----------------------------------------------------
|
||||
// <other stuff>
|
||||
//
|
||||
// For our purposes we only care about the first portion of the file noted
|
||||
// above which contains memory alloations (both sections). The term
|
||||
// "orphaned" is misleading, it appears that every allocation not by the
|
||||
// first process is considered orphaned on FxOS devices.
|
||||
|
||||
// The first three fields of each entry interest us:
|
||||
// 1) client - Essentially the process name. We limit client names to 63
|
||||
// characters, in theory they should never be greater than 15
|
||||
// due to thread name length limitations.
|
||||
// 2) pid - The ID of the allocating process, read as a uint32_t.
|
||||
// 3) size - The size of the allocation in bytes, read as as a uint64_t.
|
||||
const char* const kFormatString = "%63s %" SCNu32 " %" SCNu64;
|
||||
const size_t kNumFields = 3;
|
||||
const size_t kStringSize = 64;
|
||||
const char* const kIonIommuPath = "/sys/kernel/debug/ion/iommu";
|
||||
|
||||
FILE* iommu = fopen(kIonIommuPath, "r");
|
||||
if (!iommu) {
|
||||
if (NS_WARN_IF(errno != ENOENT)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// If ENOENT, system doesn't use ION.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
AutoFile iommuGuard(iommu);
|
||||
|
||||
const size_t kBufferLen = 256;
|
||||
char buffer[kBufferLen];
|
||||
char client[kStringSize];
|
||||
uint32_t pid;
|
||||
uint64_t size;
|
||||
|
||||
// Ignore the header line.
|
||||
fgets(buffer, kBufferLen, iommu);
|
||||
|
||||
// Ignore the separator line.
|
||||
fgets(buffer, kBufferLen, iommu);
|
||||
|
||||
const char* const kSep = "----";
|
||||
const size_t kSepLen = 4;
|
||||
|
||||
// Read non-orphaned entries.
|
||||
while (fgets(buffer, kBufferLen, iommu) &&
|
||||
strncmp(kSep, buffer, kSepLen) != 0) {
|
||||
if (sscanf(buffer, kFormatString, client, &pid, &size) == kNumFields) {
|
||||
nsPrintfCString entryPath("ion-memory/%s (pid=%d)", client, pid);
|
||||
REPORT(entryPath,
|
||||
size,
|
||||
NS_LITERAL_CSTRING("An ION kernel memory allocation."));
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore the orphaned header.
|
||||
fgets(buffer, kBufferLen, iommu);
|
||||
|
||||
// Read orphaned entries.
|
||||
while (fgets(buffer, kBufferLen, iommu) &&
|
||||
strncmp(kSep, buffer, kSepLen) != 0) {
|
||||
if (sscanf(buffer, kFormatString, client, &pid, &size) == kNumFields) {
|
||||
nsPrintfCString entryPath("ion-memory/%s (pid=%d)", client, pid);
|
||||
REPORT(entryPath,
|
||||
size,
|
||||
NS_LITERAL_CSTRING("An ION kernel memory allocation."));
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore the rest of the file.
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
ReadSizeFromFile(const char* aFilename)
|
||||
{
|
||||
@ -866,20 +990,6 @@ private:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
struct AutoDir
|
||||
{
|
||||
AutoDir(DIR* aDir) : mDir(aDir) {}
|
||||
~AutoDir() { closedir(mDir); };
|
||||
DIR* mDir;
|
||||
};
|
||||
|
||||
struct AutoFile
|
||||
{
|
||||
AutoFile(FILE* aFile) : mFile(aFile) {}
|
||||
~AutoFile() { fclose(mFile); }
|
||||
FILE* mFile;
|
||||
};
|
||||
|
||||
nsresult
|
||||
CollectKgslReports(nsIHandleReportCallback* aHandleReport,
|
||||
nsISupports* aData)
|
||||
|
Loading…
Reference in New Issue
Block a user