19357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed/* 29357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed * Copyright (C) 2013 The Android Open Source Project 39357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed * 49357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed * Licensed under the Apache License, Version 2.0 (the "License"); 59357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed * you may not use this file except in compliance with the License. 69357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed * You may obtain a copy of the License at 79357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed * 89357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed * http://www.apache.org/licenses/LICENSE-2.0 99357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed * 109357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed * Unless required by applicable law or agreed to in writing, software 119357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed * distributed under the License is distributed on an "AS IS" BASIS, 129357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed * See the License for the specific language governing permissions and 149357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed * limitations under the License. 159357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed */ 169357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed 179357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed#include <errno.h> 189357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed#include <stdbool.h> 199357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed#include <stdio.h> 209357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed#include <string.h> 219357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed#include <sys/mman.h> 229357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed 239357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed#include <hardware/memtrack.h> 249357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed 259357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed#include "memtrack_msm.h" 269357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed 279357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) 289357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed#define min(x, y) ((x) < (y) ? (x) : (y)) 299357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed 309357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmedstruct memtrack_record record_templates[] = { 319357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed { 329357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed .flags = MEMTRACK_FLAG_SMAPS_ACCOUNTED | 339357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed MEMTRACK_FLAG_PRIVATE | 349357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed MEMTRACK_FLAG_NONSECURE, 359357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed }, 369357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed { 379357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed .flags = MEMTRACK_FLAG_SMAPS_UNACCOUNTED | 389357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed MEMTRACK_FLAG_PRIVATE | 399357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed MEMTRACK_FLAG_NONSECURE, 409357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed }, 419357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed}; 429357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed 439357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmedint kgsl_memtrack_get_memory(pid_t pid, enum memtrack_type type, 449357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed struct memtrack_record *records, 459357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed size_t *num_records) 469357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed{ 479357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed size_t allocated_records = min(*num_records, ARRAY_SIZE(record_templates)); 489357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed int i; 499357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed FILE *fp; 509357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed char line[1024]; 519357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed char tmp[128]; 52f41c66785a46545ea48fddfb24e39a29a35bed58Steve Rossbach bool is_surfaceflinger = false; 539357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed size_t accounted_size = 0; 549357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed size_t unaccounted_size = 0; 559357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed 569357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed *num_records = ARRAY_SIZE(record_templates); 579357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed 589357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed /* fastpath to return the necessary number of records */ 599357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed if (allocated_records == 0) { 609357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed return 0; 619357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed } 629357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed 63f41c66785a46545ea48fddfb24e39a29a35bed58Steve Rossbach snprintf(tmp, sizeof(tmp), "/proc/%d/cmdline", pid); 64f41c66785a46545ea48fddfb24e39a29a35bed58Steve Rossbach fp = fopen(tmp, "r"); 65f41c66785a46545ea48fddfb24e39a29a35bed58Steve Rossbach if (fp != NULL) { 66f41c66785a46545ea48fddfb24e39a29a35bed58Steve Rossbach if (fgets(line, sizeof(line), fp)) { 67f41c66785a46545ea48fddfb24e39a29a35bed58Steve Rossbach if (strcmp(line, "/system/bin/surfaceflinger") == 0) 68f41c66785a46545ea48fddfb24e39a29a35bed58Steve Rossbach is_surfaceflinger = true; 69f41c66785a46545ea48fddfb24e39a29a35bed58Steve Rossbach } 70f41c66785a46545ea48fddfb24e39a29a35bed58Steve Rossbach fclose(fp); 71f41c66785a46545ea48fddfb24e39a29a35bed58Steve Rossbach } 72f41c66785a46545ea48fddfb24e39a29a35bed58Steve Rossbach 739357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed memcpy(records, record_templates, 749357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed sizeof(struct memtrack_record) * allocated_records); 759357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed 769357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed sprintf(tmp, "/d/kgsl/proc/%d/mem", pid); 779357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed fp = fopen(tmp, "r"); 789357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed if (fp == NULL) { 799357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed return -errno; 809357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed } 819357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed 82d721a674a55fadafb9007e52aee6569fba51e7dbCarter Cooper /* Go through each line of <pid>/mem file and for every entry of type "gpumem" 83d721a674a55fadafb9007e52aee6569fba51e7dbCarter Cooper * check if the gpubuffer entry is usermapped or not. If the entry is usermapped 84d721a674a55fadafb9007e52aee6569fba51e7dbCarter Cooper * count the entry as accounted else count the entry as unaccounted. 85d721a674a55fadafb9007e52aee6569fba51e7dbCarter Cooper */ 869357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed while (1) { 879357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed unsigned long size; 889357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed char line_type[7]; 89d721a674a55fadafb9007e52aee6569fba51e7dbCarter Cooper char flags[7]; 90f41c66785a46545ea48fddfb24e39a29a35bed58Steve Rossbach char line_usage[19]; 919357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed int ret; 929357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed 939357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed if (fgets(line, sizeof(line), fp) == NULL) { 949357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed break; 959357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed } 969357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed 979357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed /* Format: 989357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed * gpuaddr useraddr size id flags type usage sglen 99d721a674a55fadafb9007e52aee6569fba51e7dbCarter Cooper * 545ba000 545ba000 4096 1 ----pY gpumem arraybuffer 1 1009357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed */ 101d721a674a55fadafb9007e52aee6569fba51e7dbCarter Cooper ret = sscanf(line, "%*x %*lx %lu %*d %6s %6s %18s %*d\n", 102d721a674a55fadafb9007e52aee6569fba51e7dbCarter Cooper &size, flags, line_type, line_usage); 103f41c66785a46545ea48fddfb24e39a29a35bed58Steve Rossbach if (ret != 4) { 1049357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed continue; 1059357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed } 1069357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed 1079357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed if (type == MEMTRACK_TYPE_GL && strcmp(line_type, "gpumem") == 0) { 108d721a674a55fadafb9007e52aee6569fba51e7dbCarter Cooper if (flags[6] == 'Y') 109d721a674a55fadafb9007e52aee6569fba51e7dbCarter Cooper accounted_size += size; 110d721a674a55fadafb9007e52aee6569fba51e7dbCarter Cooper else 1119357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed unaccounted_size += size; 1129357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed } else if (type == MEMTRACK_TYPE_GRAPHICS && strcmp(line_type, "ion") == 0) { 113f41c66785a46545ea48fddfb24e39a29a35bed58Steve Rossbach if (!is_surfaceflinger || strcmp(line_usage, "egl_image") != 0) { 114f41c66785a46545ea48fddfb24e39a29a35bed58Steve Rossbach unaccounted_size += size; 115f41c66785a46545ea48fddfb24e39a29a35bed58Steve Rossbach } 1169357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed } 1179357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed } 1189357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed 1199357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed if (allocated_records > 0) { 1209357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed records[0].size_in_bytes = accounted_size; 1219357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed } 1229357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed if (allocated_records > 1) { 1239357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed records[1].size_in_bytes = unaccounted_size; 1249357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed } 1259357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed 1269357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed fclose(fp); 1279357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed 1289357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed return 0; 1299357ed10419855c026cc56995c95d372cfc2feefNaseer Ahmed} 130