resource: process: Handle the case that target cannot support taskstats 65/279765/3
authorDongwoo Lee <dwoo08.lee@samsung.com>
Wed, 17 Aug 2022 08:42:43 +0000 (17:42 +0900)
committerDongwoo Lee <dwoo08.lee@samsung.com>
Thu, 18 Aug 2022 02:27:56 +0000 (11:27 +0900)
Since PROCESS resource has some attributes which require taskstats,
those attributes are mark to unsupported or provided by other methods
when the target does not support taskstats.

Change-Id: I83a0eab243367f59c518d1b1c422b741f3e611bb
Signed-off-by: Dongwoo Lee <dwoo08.lee@samsung.com>
src/resource/resource-process.c

index 633fc78..192d91e 100644 (file)
@@ -41,6 +41,7 @@ struct process_context {
 };
 
 static long jiffy;
+static int taskstat_support = -1;
 
 static int process_get_cpu_util(struct resource *res,
                                const struct resource_attribute *attr,
@@ -194,6 +195,21 @@ static int process_get_context_data(struct resource *res,
 
        switch (attr->id) {
        case PROCESS_ATTR_NAME:
+               if (!taskstat_support && (strlen(ctx->comm) == 0)) {
+                       char *stat_fields[PROCESS_STAT_FIELD_MAX];
+                       char buffer[BUFF_MAX];
+                       int ret, len;
+
+                       ret = kernel_get_process_stat_fields(ctx->tgid, buffer,
+                                                            BUFF_MAX, stat_fields);
+                       if (ret < 0)
+                               break;
+
+                       len = strlen(stat_fields[PROCESS_STAT_FIELD_COMM]) - 2/* '(', ')' */;
+                       len = (len < TS_COMM_LEN - 1) ? len : TS_COMM_LEN - 1;
+                       strncpy(ctx->comm, stat_fields[PROCESS_STAT_FIELD_COMM] + 1, len);
+               }
+
                strncpy((char *)data, ctx->comm, TS_COMM_LEN);
                break;
        case PROCESS_ATTR_PGID:
@@ -213,6 +229,19 @@ static int process_get_context_data(struct resource *res,
                *((int *)data) = ctx->pgid;
                break;
        case PROCESS_ATTR_PPID:
+               if (ctx->ppid < 0) {
+                       char *stat_fields[PROCESS_STAT_FIELD_MAX];
+                       char buffer[BUFF_MAX];
+                       int ret;
+
+                       ret = kernel_get_process_stat_fields(ctx->tgid, buffer,
+                                                            BUFF_MAX, stat_fields);
+                       if (ret < 0)
+                               break;
+
+                       ctx->ppid = atoi(stat_fields[PROCESS_STAT_FIELD_PPID]);
+               }
+
                *((int *)data) = ctx->ppid;
                break;
        }
@@ -220,6 +249,12 @@ static int process_get_context_data(struct resource *res,
        return 0;
 }
 
+static bool process_check_taskstat_support(struct resource *resource,
+                                           const struct resource_attribute *attr)
+{
+       return !!taskstat_support;
+}
+
 static bool process_check_gpu_support(struct resource *resource,
                                            const struct resource_attribute *attr)
 {
@@ -233,7 +268,7 @@ static const struct resource_attribute process_attrs[] = {
                .type   = DATA_TYPE_DOUBLE,
                .ops    = {
                        .get = process_get_cpu_util,
-                       .is_supported = resource_attr_supported_always,
+                       .is_supported = process_check_taskstat_support,
                },
        }, {
                .name   = "PROCESS_ATTR_MEM_VIRT",
@@ -241,7 +276,7 @@ static const struct resource_attribute process_attrs[] = {
                .type   = DATA_TYPE_UINT64,
                .ops    = {
                        .get = process_get_mem_attrs,
-                       .is_supported = resource_attr_supported_always,
+                       .is_supported = process_check_taskstat_support,
                },
        }, {
                .name   = "PROCESS_ATTR_MEM_RSS",
@@ -249,7 +284,7 @@ static const struct resource_attribute process_attrs[] = {
                .type   = DATA_TYPE_UINT64,
                .ops    = {
                        .get = process_get_mem_attrs,
-                       .is_supported = resource_attr_supported_always,
+                       .is_supported = process_check_taskstat_support,
                },
        }, {
                .name   = "PROCESS_ATTR_MEM_RSS_PERCENT",
@@ -257,7 +292,7 @@ static const struct resource_attribute process_attrs[] = {
                .type   = DATA_TYPE_DOUBLE,
                .ops    = {
                        .get = process_get_mem_attrs,
-                       .is_supported = resource_attr_supported_always,
+                       .is_supported = process_check_taskstat_support,
                },
        }, {
                .name   = "PROCESS_ATTR_DISK_READ_PER_SEC",
@@ -265,7 +300,7 @@ static const struct resource_attribute process_attrs[] = {
                .type   = DATA_TYPE_DOUBLE,
                .ops    = {
                        .get = process_get_disk_attrs,
-                       .is_supported = resource_attr_supported_always,
+                       .is_supported = process_check_taskstat_support,
                },
        }, {
                .name   = "PROCESS_ATTR_DISK_WRITE_PER_SEC",
@@ -273,7 +308,7 @@ static const struct resource_attribute process_attrs[] = {
                .type   = DATA_TYPE_DOUBLE,
                .ops    = {
                        .get = process_get_disk_attrs,
-                       .is_supported = resource_attr_supported_always,
+                       .is_supported = process_check_taskstat_support,
                },
        }, {
                .name   = "PROCESS_ATTR_NAME",
@@ -379,19 +414,29 @@ static int process_setup_tgid(struct resource *res,
        ctx->prev_total_time = get_total_cpu_time();
 
        /* update initial status */
-       ret = kernel_get_thread_group_taskstats(&ctx->curr, ctx->tgid, true);
-       if (ret < 0)
-               return ret;
+       if (taskstat_support) {
+               ret = kernel_get_thread_group_taskstats(&ctx->curr, ctx->tgid, true);
+               if (ret < 0)
+                       return ret;
+
+               memcpy(ctx->comm, ctx->curr.ac_comm, strlen(ctx->curr.ac_comm) + 1);
+               ctx->ppid = ctx->curr.ac_ppid;
+       } else {
+               /*
+                * if taskstat is not supported, comm, pgid and ppid is retrieved
+                * from procfs status lazily.
+                *
+                * ctx->comm is now "\0" so it is treated as not initialized.
+                */
+               ctx->ppid = -1;
+       }
+
+       ctx->pgid = -1;
 
        ret = kernel_get_thread_group_map_info(&ctx->map_info, ctx->tgid, include_gpu_mem);
        if (ret < 0)
                return ret;
 
-       memcpy(ctx->comm, ctx->curr.ac_comm, strlen(ctx->curr.ac_comm) + 1);
-
-       ctx->pgid = -1;
-       ctx->ppid = ctx->curr.ac_ppid;
-
        return 0;
 }
 
@@ -421,11 +466,12 @@ static int process_prepare_update(struct resource *res)
 
        include_gpu_mem = is_resource_attr_interested(res, PROCESS_GROUP_ATTR_MEM_GPU);
 
-       memcpy(&ctx->prev, &ctx->curr, sizeof(struct taskstats));
-
-       ret = kernel_get_thread_group_taskstats(&ctx->curr, ctx->tgid, false);
-       if (ret < 0)
-               return ret;
+       if (taskstat_support) {
+               memcpy(&ctx->prev, &ctx->curr, sizeof(struct taskstats));
+               ret = kernel_get_thread_group_taskstats(&ctx->curr, ctx->tgid, false);
+               if (ret < 0)
+                       return ret;
+       }
 
        ret = kernel_get_thread_group_map_info(&ctx->map_info, ctx->tgid, include_gpu_mem);
        if (ret < 0)
@@ -453,6 +499,9 @@ static int process_init(struct resource *res)
                        return -EINVAL;
        }
 
+       if (taskstat_support < 0)
+               taskstat_support = (int)kernel_check_taskstat_support();
+
        ctx = calloc(1, sizeof(struct process_context));
        if (!ctx)
                return -ENOMEM;