From: Dongwoo Lee Date: Thu, 24 Feb 2022 11:40:11 +0000 (+0900) Subject: resource: Rework resource creation and initialization X-Git-Tag: accepted/tizen/unified/20220313.205607~18 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1eb3e815b9d4165c92cd6a54814fcaa2e7ef5622;p=platform%2Fcore%2Fsystem%2Fpass.git resource: Rework resource creation and initialization Change-Id: I386e277a20418b4030d3d5a63dcf10ea15898c6c Signed-off-by: Dongwoo Lee --- diff --git a/include/util/resource.h b/include/util/resource.h index a2d3765..a5057ec 100644 --- a/include/util/resource.h +++ b/include/util/resource.h @@ -68,6 +68,23 @@ struct resource_attribute { const struct resource_attribute_ops ops; }; +struct resource_control; + +struct resource_control_ops { + const int (*set)(const struct resource *res, + const struct resource_control *ctrl, + const void *data); + const int (*get)(const struct resource *res, + const struct resource_control *ctrl, + void **data); +}; + +struct resource_control { + const char name[BUFF_MAX]; + const u_int64_t id; + const struct resource_control_ops ops; +}; + struct resource_driver_ops { int (*init)(struct resource *res); void (*exit)(struct resource *res); @@ -78,15 +95,13 @@ struct resource_driver_ops { int (*prepare_update)(struct resource *res); }; -/* resource driver flags */ -#define RESOURCE_DRIVER_NO_DEVICE BIT32(1) - struct resource_driver { const char *name; const int type; - const int flags; const int num_attrs; const struct resource_attribute *attrs; + const int num_ctrls; + const struct resource_control *ctrls; const struct resource_driver_ops ops; }; @@ -105,13 +120,13 @@ struct resource { char *name; const struct resource_driver *driver; int type; - int index; - void *user_data; void *priv; int num_attrs; const struct resource_attribute *attrs; struct resource_attribute_value *attrs_value; + int num_ctrls; + const struct resource_control *ctrls; u_int64_t attr_interest; }; @@ -136,9 +151,12 @@ int add_resource_device(struct resource_device *resource_device); void remove_resource_device(struct resource_device *resource_device); /* Create/delete resource instance */ -struct resource *create_resource(int resource_type, int resource_index, void *user_data); +struct resource *create_resource(int resource_type); void delete_resource(struct resource *resource); +/* Handle resource control */ +int set_resource_control(struct resource *resource, u_int64_t ctrl_id, const void *data); + /* Handle resource attribute */ int update_resource_attrs(struct resource *resource); const struct resource_attribute *get_resource_attr(struct resource *resource, u_int64_t attr_id); diff --git a/lib/tmonitor/tmonitor.h b/lib/tmonitor/tmonitor.h index 5bc637c..3c4a667 100644 --- a/lib/tmonitor/tmonitor.h +++ b/lib/tmonitor/tmonitor.h @@ -51,6 +51,8 @@ extern "C" { #define CPU_ONLINE_CPU BIT(6) #define CPU_TEMPERATURE BIT(7) +#define CPU_CTRL_CLUSTER_ID BIT(0) + #define BUS_CUR_FREQ BIT(0) #define BUS_MIN_FREQ BIT(1) #define BUS_MAX_FREQ BIT(2) @@ -58,6 +60,8 @@ extern "C" { #define BUS_AVAILABLE_MAX_FREQ BIT(4) #define BUS_CUR_GOVERNOR BIT(5) +#define BUS_CTRL_DEVICE_ID BIT(0) + #define GPU_CUR_FREQ BIT(0) #define GPU_MIN_FREQ BIT(1) #define GPU_MAX_FREQ BIT(2) @@ -66,6 +70,8 @@ extern "C" { #define GPU_CUR_GOVERNOR BIT(5) #define GPU_TEMPERATURE BIT(6) +#define GPU_CTRL_DEVICE_ID BIT(0) + #define MEMORY_TOTAL BIT(0) #define MEMORY_AVAILABLE BIT(1) #define MEMORY_FREE BIT(2) @@ -81,6 +87,8 @@ extern "C" { #define DISPLAY_FPS BIT(0) +#define DISPLAY_CTRL_DEVICE_ID BIT(0) + #define SYSTEM_CPU_UTIL BIT(0) #define SYSTEM_CPU_USER_UTIL BIT(1) #define SYSTEM_CPU_SYS_UTIL BIT(2) @@ -98,6 +106,8 @@ extern "C" { #define PROCESS_DISK_WRITE BIT(5) #define PROCESS_COMM BIT(6) +#define PROCESS_CTRL_TGID BIT(0) + /** * @brief Initialize the tizen monitor * @param[in] Timer period (unit: millisecond, minimum value is 100ms) diff --git a/src/resource/resource-battery.c b/src/resource/resource-battery.c index 0e2364c..d621c37 100644 --- a/src/resource/resource-battery.c +++ b/src/resource/resource-battery.c @@ -151,6 +151,5 @@ static const struct resource_driver battery_resource_driver = { .type = RESOURCE_TYPE_BATTERY, .attrs = battery_attrs, .num_attrs = ARRAY_SIZE(battery_attrs), - .flags = RESOURCE_DRIVER_NO_DEVICE, }; RESOURCE_DRIVER_REGISTER(&battery_resource_driver) diff --git a/src/resource/resource-bus.c b/src/resource/resource-bus.c index f76f047..9ca48d9 100644 --- a/src/resource/resource-bus.c +++ b/src/resource/resource-bus.c @@ -32,16 +32,29 @@ #include +struct bus_context { + char *device_name; + int index; +}; + static int bus_get_cur_freq(const struct resource *res, const struct resource_attribute *attr, void **data) { + struct bus_context *ctx; int val; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) return -EINVAL; - val = hal_power_dvfs_get_curr_freq(res->type, res->name); + ctx = res->priv; + + if (!ctx->device_name) { + _E("%s: BUS_CTRL_DEVICE_ID is not yet initialized\n", res->name); + return -EINVAL; + } + + val = hal_power_dvfs_get_curr_freq(res->type, ctx->device_name); if (val < 0) return -EINVAL; @@ -54,12 +67,20 @@ static int bus_get_min_freq(const struct resource *res, const struct resource_attribute *attr, void **data) { + struct bus_context *ctx; int val; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) return -EINVAL; - val = hal_power_dvfs_get_min_freq(res->type, res->name); + ctx = res->priv; + + if (!ctx->device_name) { + _E("%s: BUS_CTRL_DEVICE_ID is not yet initialized\n", res->name); + return -EINVAL; + } + + val = hal_power_dvfs_get_min_freq(res->type, ctx->device_name); if (val < 0) return -EINVAL; @@ -72,12 +93,20 @@ static int bus_get_max_freq(const struct resource *res, const struct resource_attribute *attr, void **data) { + struct bus_context *ctx; int val; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) + return -EINVAL; + + ctx = res->priv; + + if (!ctx->device_name) { + _E("%s: BUS_CTRL_DEVICE_ID is not yet initialized\n", res->name); return -EINVAL; + } - val = hal_power_dvfs_get_max_freq(res->type, res->name); + val = hal_power_dvfs_get_max_freq(res->type, ctx->device_name); if (val < 0) return -EINVAL; @@ -90,12 +119,20 @@ static int bus_get_available_min_freq(const struct resource *res, const struct resource_attribute *attr, void **data) { + struct bus_context *ctx; int val; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) + return -EINVAL; + + ctx = res->priv; + + if (!ctx->device_name) { + _E("%s: BUS_CTRL_DEVICE_ID is not yet initialized\n", res->name); return -EINVAL; + } - val = hal_power_dvfs_get_available_min_freq(res->type, res->name); + val = hal_power_dvfs_get_available_min_freq(res->type, ctx->device_name); if (val < 0) return -EINVAL; @@ -108,12 +145,20 @@ static int bus_get_available_max_freq(const struct resource *res, const struct resource_attribute *attr, void **data) { + struct bus_context *ctx; int val; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) + return -EINVAL; + + ctx = res->priv; + + if (!ctx->device_name) { + _E("%s: BUS_CTRL_DEVICE_ID is not yet initialized\n", res->name); return -EINVAL; + } - val = hal_power_dvfs_get_available_max_freq(res->type, res->name); + val = hal_power_dvfs_get_available_max_freq(res->type, ctx->device_name); if (val < 0) return -EINVAL; @@ -126,13 +171,21 @@ static int bus_get_curr_governor(const struct resource *res, const struct resource_attribute *attr, void **data) { + struct bus_context *ctx; char buf[BUFF_MAX]; int val; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) + return -EINVAL; + + ctx = res->priv; + + if (!ctx->device_name) { + _E("%s: BUS_CTRL_DEVICE_ID is not yet initialized\n", res->name); return -EINVAL; + } - val = hal_power_dvfs_get_curr_governor(res->type, res->name, buf); + val = hal_power_dvfs_get_curr_governor(res->type, ctx->device_name, buf); if (val < 0) return -EINVAL; @@ -189,10 +242,84 @@ static const struct resource_attribute bus_attrs[] = { }, }; +static int bus_setup_device_id(const struct resource *res, + const struct resource_control *ctrl, + const void *data) +{ + struct bus_context *ctx; + const struct resource_device *device; + int device_id = (int)(intptr_t)data; + + if (!res || !res->priv || !ctrl) + return -EINVAL; + + device = find_resource_device(res->type, device_id); + if (!device) { + _E("Not available resource: type: %s, index: %d\n", + res->name, device_id); + return -EINVAL; + } + + ctx = res->priv; + + if (ctx->device_name) + free(ctx->device_name); + + ctx->device_name = g_strdup(device->name); + ctx->index = device_id; + + return 0; +} + +static const struct resource_control bus_ctrls[] = { + { + .name = "BUS_CTRL_DEVICE_ID", + .id = BUS_CTRL_DEVICE_ID, + .ops = { + .set = bus_setup_device_id, + }, + }, +}; + +static int bus_init(struct resource *res) +{ + struct bus_context *ctx; + + ctx = calloc(1, sizeof(struct bus_context)); + if (!ctx) + return -ENOMEM; + + res->priv = ctx; + + return 0; +} + +static void bus_exit(struct resource *res) +{ + struct bus_context *ctx; + + if (res && res->priv) { + ctx = res->priv; + if (ctx->device_name) { + free(ctx->device_name); + ctx->device_name = NULL; + } + free(ctx); + res->priv = NULL; + } +} + static const struct resource_driver bus_resource_driver = { .name = "Memory Bus", .type = RESOURCE_TYPE_BUS, .attrs = bus_attrs, .num_attrs = ARRAY_SIZE(bus_attrs), + .ctrls = bus_ctrls, + .num_ctrls = ARRAY_SIZE(bus_ctrls), + .ops = { + .init = bus_init, + .exit = bus_exit, + }, }; RESOURCE_DRIVER_REGISTER(&bus_resource_driver) + diff --git a/src/resource/resource-cpu.c b/src/resource/resource-cpu.c index 8d288f4..9930016 100644 --- a/src/resource/resource-cpu.c +++ b/src/resource/resource-cpu.c @@ -32,16 +32,29 @@ #include +struct cpu_context { + char *device_name; + int index; +}; + static int cpu_get_cur_freq(const struct resource *res, const struct resource_attribute *attr, void **data) { + struct cpu_context *ctx; int val; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) return -EINVAL; - val = hal_power_dvfs_get_curr_freq(res->type, res->name); + ctx = res->priv; + + if (!ctx->device_name) { + _E("%s: CPU_CTRL_CLUSTER_ID is not yet initialized\n", res->name); + return -EINVAL; + } + + val = hal_power_dvfs_get_curr_freq(res->type, ctx->device_name); if (val < 0) return -EINVAL; @@ -54,12 +67,20 @@ static int cpu_get_min_freq(const struct resource *res, const struct resource_attribute *attr, void **data) { + struct cpu_context *ctx; int val; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) return -EINVAL; - val = hal_power_dvfs_get_min_freq(res->type, res->name); + ctx = res->priv; + + if (!ctx->device_name) { + _E("%s: CPU_CTRL_CLUSTER_ID is not yet initialized\n", res->name); + return -EINVAL; + } + + val = hal_power_dvfs_get_min_freq(res->type, ctx->device_name); if (val < 0) return -EINVAL; @@ -72,12 +93,20 @@ static int cpu_get_max_freq(const struct resource *res, const struct resource_attribute *attr, void **data) { + struct cpu_context *ctx; int val; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) + return -EINVAL; + + ctx = res->priv; + + if (!ctx->device_name) { + _E("%s: CPU_CTRL_CLUSTER_ID is not yet initialized\n", res->name); return -EINVAL; + } - val = hal_power_dvfs_get_max_freq(res->type, res->name); + val = hal_power_dvfs_get_max_freq(res->type, ctx->device_name); if (val < 0) return -EINVAL; @@ -90,12 +119,20 @@ static int cpu_get_available_min_freq(const struct resource *res, const struct resource_attribute *attr, void **data) { + struct cpu_context *ctx; int val; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) + return -EINVAL; + + ctx = res->priv; + + if (!ctx->device_name) { + _E("%s: CPU_CTRL_CLUSTER_ID is not yet initialized\n", res->name); return -EINVAL; + } - val = hal_power_dvfs_get_available_min_freq(res->type, res->name); + val = hal_power_dvfs_get_available_min_freq(res->type, ctx->device_name); if (val < 0) return -EINVAL; @@ -108,12 +145,20 @@ static int cpu_get_available_max_freq(const struct resource *res, const struct resource_attribute *attr, void **data) { + struct cpu_context *ctx; int val; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) + return -EINVAL; + + ctx = res->priv; + + if (!ctx->device_name) { + _E("%s: CPU_CTRL_CLUSTER_ID is not yet initialized\n", res->name); return -EINVAL; + } - val = hal_power_dvfs_get_available_max_freq(res->type, res->name); + val = hal_power_dvfs_get_available_max_freq(res->type, ctx->device_name); if (val < 0) return -EINVAL; @@ -126,13 +171,21 @@ static int cpu_get_curr_governor(const struct resource *res, const struct resource_attribute *attr, void **data) { + struct cpu_context *ctx; char buf[BUFF_MAX]; int val; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) + return -EINVAL; + + ctx = res->priv; + + if (!ctx->device_name) { + _E("%s: CPU_CTRL_CLUSTER_ID is not yet initialized\n", res->name); return -EINVAL; + } - val = hal_power_dvfs_get_curr_governor(res->type, res->name, buf); + val = hal_power_dvfs_get_curr_governor(res->type, ctx->device_name, buf); if (val < 0) return -EINVAL; @@ -217,10 +270,84 @@ static const struct resource_attribute cpu_attrs[] = { }, }; +static int cpu_setup_cluster_id(const struct resource *res, + const struct resource_control *ctrl, + const void *data) +{ + struct cpu_context *ctx; + const struct resource_device *device; + int resource_index = (int)(intptr_t)data; + + if (!res || !res->priv || !ctrl) + return -EINVAL; + + device = find_resource_device(res->type, resource_index); + if (!device) { + _E("Not available resource: type: %s, index: %d\n", + res->name, resource_index); + return -EINVAL; + } + + ctx = res->priv; + + if (ctx->device_name) + free(ctx->device_name); + + ctx->device_name = g_strdup(device->name); + ctx->index = resource_index; + + return 0; +} + +static const struct resource_control cpu_ctrls[] = { + { + .name = "CPU_CTRL_CLUSTER_ID", + .id = CPU_CTRL_CLUSTER_ID, + .ops = { + .set = cpu_setup_cluster_id, + }, + }, +}; + +static int cpu_init(struct resource *res) +{ + struct cpu_context *ctx; + + ctx = calloc(1, sizeof(struct cpu_context)); + if (!ctx) + return -ENOMEM; + + res->priv = ctx; + + return 0; +} + +static void cpu_exit(struct resource *res) +{ + struct cpu_context *ctx; + + if (res && res->priv) { + ctx = res->priv; + if (ctx->device_name) { + free(ctx->device_name); + ctx->device_name = NULL; + } + free(ctx); + res->priv = NULL; + } +} + static const struct resource_driver cpu_resource_driver = { .name = "CPU", .type = RESOURCE_TYPE_CPU, .attrs = cpu_attrs, .num_attrs = ARRAY_SIZE(cpu_attrs), + .ctrls = cpu_ctrls, + .num_ctrls = ARRAY_SIZE(cpu_ctrls), + .ops = { + .init = cpu_init, + .exit = cpu_exit, + }, }; RESOURCE_DRIVER_REGISTER(&cpu_resource_driver) + diff --git a/src/resource/resource-display.c b/src/resource/resource-display.c index 7210af2..f3b7af9 100644 --- a/src/resource/resource-display.c +++ b/src/resource/resource-display.c @@ -55,11 +55,19 @@ static int display_get_fps(const struct resource *res, GVariant *result, *value; GError *err = NULL; struct display_fps_data fps_data; + int *disp_id; int ret = 0; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) return -EINVAL; + disp_id = res->priv; + + if (*disp_id < 0) { + _E("%s: DISPLAY_CTRL_DEVICE_ID is not yet initialized\n", res->name); + return -EINVAL; + } + /* Connect dbus interface and receive message */ conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); if (err) { @@ -92,13 +100,13 @@ static int display_get_fps(const struct resource *res, /* Parse the received data */ result = g_variant_get_child_value(g_dbus_message_get_body(reply), 0); - if (g_variant_n_children(result) <= res->index) { + if (g_variant_n_children(result) == 0) { fps_data.fps = 0.0; goto out; } /* Get the fps information according to the index of resource_device */ - value = g_variant_get_child_value(result, res->index); + value = g_variant_get_child_value(result, *disp_id); g_variant_get(value, "(usiud)", &fps_data.type, fps_data.output, &fps_data.zpos, &fps_data.window, &fps_data.fps); @@ -127,11 +135,62 @@ static const struct resource_attribute display_attrs[] = { }, }; +static int display_setup_device_id(const struct resource *res, + const struct resource_control *ctrl, + const void *data) +{ + int *disp_id; + + if (!res || !res->priv || !ctrl) + return -EINVAL; + + disp_id = res->priv; + + *disp_id = (int)(intptr_t)data; + + return 0; +} + +static const struct resource_control display_ctrls[] = { + { + .name = "DISPLAY_CTRL_DEVICE_ID", + .id = DISPLAY_CTRL_DEVICE_ID, + .ops = { + .set = display_setup_device_id, + }, + }, +}; + +static int display_init(struct resource *res) +{ + int *disp_id; + + disp_id = malloc(sizeof(int)); + if (!disp_id) + return -ENOMEM; + + *disp_id = -1; + + res->priv = disp_id; + + return 0; +} + +static void display_exit(struct resource *res) +{ + if (res && res->priv) + free(res->priv); +} static const struct resource_driver display_resource_driver = { .name = "DISPLAY", .type = RESOURCE_TYPE_DISPLAY, .attrs = display_attrs, .num_attrs = ARRAY_SIZE(display_attrs), - .flags = RESOURCE_DRIVER_NO_DEVICE, + .ctrls = display_ctrls, + .num_ctrls = ARRAY_SIZE(display_ctrls), + .ops = { + .init = display_init, + .exit = display_exit, + }, }; RESOURCE_DRIVER_REGISTER(&display_resource_driver) diff --git a/src/resource/resource-gpu.c b/src/resource/resource-gpu.c index e7afa19..1c27599 100644 --- a/src/resource/resource-gpu.c +++ b/src/resource/resource-gpu.c @@ -32,16 +32,29 @@ #include +struct gpu_context { + char *device_name; + int index; +}; + static int gpu_get_cur_freq(const struct resource *res, const struct resource_attribute *attr, void **data) { + struct gpu_context *ctx; int val; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) return -EINVAL; - val = hal_power_dvfs_get_curr_freq(res->type, res->name); + ctx = res->priv; + + if (!ctx->device_name) { + _E("%s: GPU_CTRL_DEVICE_ID is not yet initialized\n", res->name); + return -EINVAL; + } + + val = hal_power_dvfs_get_curr_freq(res->type, ctx->device_name); if (val < 0) return -EINVAL; @@ -54,12 +67,20 @@ static int gpu_get_min_freq(const struct resource *res, const struct resource_attribute *attr, void **data) { + struct gpu_context *ctx; int val; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) return -EINVAL; - val = hal_power_dvfs_get_min_freq(res->type, res->name); + ctx = res->priv; + + if (!ctx->device_name) { + _E("%s: GPU_CTRL_DEVICE_ID is not yet initialized\n", res->name); + return -EINVAL; + } + + val = hal_power_dvfs_get_min_freq(res->type, ctx->device_name); if (val < 0) return -EINVAL; @@ -72,12 +93,20 @@ static int gpu_get_max_freq(const struct resource *res, const struct resource_attribute *attr, void **data) { + struct gpu_context *ctx; int val; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) + return -EINVAL; + + ctx = res->priv; + + if (!ctx->device_name) { + _E("%s: GPU_CTRL_DEVICE_ID is not yet initialized\n", res->name); return -EINVAL; + } - val = hal_power_dvfs_get_max_freq(res->type, res->name); + val = hal_power_dvfs_get_available_max_freq(res->type, ctx->device_name); if (val < 0) return -EINVAL; @@ -90,12 +119,20 @@ static int gpu_get_available_min_freq(const struct resource *res, const struct resource_attribute *attr, void **data) { + struct gpu_context *ctx; int val; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) + return -EINVAL; + + ctx = res->priv; + + if (!ctx->device_name) { + _E("%s: GPU_CTRL_DEVICE_ID is not yet initialized\n", res->name); return -EINVAL; + } - val = hal_power_dvfs_get_available_min_freq(res->type, res->name); + val = hal_power_dvfs_get_available_min_freq(res->type, ctx->device_name); if (val < 0) return -EINVAL; @@ -108,12 +145,20 @@ static int gpu_get_available_max_freq(const struct resource *res, const struct resource_attribute *attr, void **data) { + struct gpu_context *ctx; int val; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) + return -EINVAL; + + ctx = res->priv; + + if (!ctx->device_name) { + _E("%s: GPU_CTRL_DEVICE_ID is not yet initialized\n", res->name); return -EINVAL; + } - val = hal_power_dvfs_get_available_max_freq(res->type, res->name); + val = hal_power_dvfs_get_available_max_freq(res->type, ctx->device_name); if (val < 0) return -EINVAL; @@ -126,13 +171,21 @@ static int gpu_get_curr_governor(const struct resource *res, const struct resource_attribute *attr, void **data) { + struct gpu_context *ctx; char buf[BUFF_MAX]; int val; - if (!res || !attr || !data) + if (!res || !res->priv || !attr || !data) + return -EINVAL; + + ctx = res->priv; + + if (!ctx->device_name) { + _E("%s: GPU_CTRL_DEVICE_ID is not yet initialized\n", res->name); return -EINVAL; + } - val = hal_power_dvfs_get_curr_governor(res->type, res->name, buf); + val = hal_power_dvfs_get_curr_governor(res->type, ctx->device_name, buf); if (val < 0) return -EINVAL; @@ -203,10 +256,84 @@ static const struct resource_attribute gpu_attrs[] = { }, }; +static int gpu_setup_device_id(const struct resource *res, + const struct resource_control *ctrl, + const void *data) +{ + struct gpu_context *ctx; + const struct resource_device *device; + int resource_index = (int)(intptr_t)data; + + if (!res || !res->priv || !ctrl) + return -EINVAL; + + device = find_resource_device(res->type, resource_index); + if (!device) { + _E("Not available resource: type: %s, index: %d\n", + res->name, resource_index); + return -EINVAL; + } + + ctx = res->priv; + + if (ctx->device_name) + free(ctx->device_name); + + ctx->device_name = g_strdup(device->name); + ctx->index = resource_index; + + return 0; +} + +static const struct resource_control gpu_ctrls[] = { + { + .name = "GPU_CTRL_DEVICE_ID", + .id = GPU_CTRL_DEVICE_ID, + .ops = { + .set = gpu_setup_device_id, + }, + }, +}; + +static int gpu_init(struct resource *res) +{ + struct gpu_context *ctx; + + ctx = calloc(1, sizeof(struct gpu_context)); + if (!ctx) + return -ENOMEM; + + res->priv = ctx; + + return 0; +} + +static void gpu_exit(struct resource *res) +{ + struct gpu_context *ctx; + + if (res && res->priv) { + ctx = res->priv; + if (ctx->device_name) { + free(ctx->device_name); + ctx->device_name = NULL; + } + free(ctx); + res->priv = NULL; + } +} + static const struct resource_driver gpu_resource_driver = { .name = "GPU", .type = RESOURCE_TYPE_GPU, .attrs = gpu_attrs, .num_attrs = ARRAY_SIZE(gpu_attrs), + .ctrls = gpu_ctrls, + .num_ctrls = ARRAY_SIZE(gpu_ctrls), + .ops = { + .init = gpu_init, + .exit = gpu_exit, + }, }; RESOURCE_DRIVER_REGISTER(&gpu_resource_driver) + diff --git a/src/resource/resource-memory.c b/src/resource/resource-memory.c index f376feb..74c8fd4 100644 --- a/src/resource/resource-memory.c +++ b/src/resource/resource-memory.c @@ -145,6 +145,5 @@ static const struct resource_driver memory_resource_driver = { .type = RESOURCE_TYPE_MEMORY, .attrs = memory_attrs, .num_attrs = ARRAY_SIZE(memory_attrs), - .flags = RESOURCE_DRIVER_NO_DEVICE, }; RESOURCE_DRIVER_REGISTER(&memory_resource_driver) diff --git a/src/resource/resource-process.c b/src/resource/resource-process.c index 4defc09..1c28294 100644 --- a/src/resource/resource-process.c +++ b/src/resource/resource-process.c @@ -29,7 +29,7 @@ #include struct process_context { - pid_t pid; + pid_t tgid; char comm[TS_COMM_LEN]; struct taskstats prev; struct taskstats curr; @@ -54,6 +54,12 @@ static int process_get_cpu_util(const struct resource *res, return -EINVAL; ctx = res->priv; + + if (!ctx->tgid) { + _E("resource %s is not yet initialized\n", res->name); + return -EINVAL; + } + prev = &ctx->prev; curr = &ctx->curr; @@ -87,6 +93,12 @@ static int process_get_mem_virt(const struct resource *res, return -EINVAL; ctx = res->priv; + + if (!ctx->tgid) { + _E("resource %s is not yet initialized\n", res->name); + return -EINVAL; + } + curr = &ctx->curr; virt = (double)curr->virtmem / (double)curr->ac_stime; @@ -109,6 +121,12 @@ static int process_get_mem_rss(const struct resource *res, return -EINVAL; ctx = res->priv; + + if (!ctx->tgid) { + _E("resource %s is not yet initialized\n", res->name); + return -EINVAL; + } + curr = &ctx->curr; rss = (double)curr->coremem / (double)curr->ac_stime; @@ -142,6 +160,12 @@ static int process_get_disk_read(const struct resource *res, return -EINVAL; ctx = res->priv; + + if (!ctx->tgid) { + _E("resource %s is not yet initialized\n", res->name); + return -EINVAL; + } + prev = &ctx->prev; curr = &ctx->curr; @@ -166,6 +190,12 @@ static int process_get_disk_write(const struct resource *res, return -EINVAL; ctx = res->priv; + + if (!ctx->tgid) { + _E("resource %s is not yet initialized\n", res->name); + return -EINVAL; + } + prev = &ctx->prev; curr = &ctx->curr; @@ -188,6 +218,12 @@ static int process_get_comm(const struct resource *res, return -EINVAL; ctx = res->priv; + + if (!ctx->tgid) { + _E("resource %s is not yet initialized\n", res->name); + return -EINVAL; + } + *data = g_strdup(ctx->comm); return 0; @@ -389,7 +425,7 @@ static int update_taskstats(struct process_context *ctx) memset(curr, 0, sizeof(struct taskstats)); - sprintf(task_dir_path, "/proc/%d/task/", ctx->pid); + sprintf(task_dir_path, "/proc/%d/task/", ctx->tgid); task_dir = opendir(task_dir_path); if (!task_dir) @@ -425,6 +461,51 @@ static int update_taskstats(struct process_context *ctx) return 0; } +static int process_setup_tgid(const struct resource *res, + const struct resource_control *ctrl, + const void *data) +{ + struct taskstats stats; + struct process_context *ctx; + u_int64_t total_memory; + int ret; + + if (!res || !res->priv || !ctrl) + return -EINVAL; + + ctx = res->priv; + + total_memory = ctx->total_memory; + memset(ctx, 0, sizeof(*ctx)); + + ctx->total_memory = total_memory; + ctx->tgid = (pid_t)(intptr_t)data; + ctx->prev_total_time = get_total_cpu_time(); + + /* update initial status */ + ret = update_taskstats(ctx); + if (ret < 0) + return -EINVAL; + + ret = query_taskstats(&stats, TASKSTATS_CMD_ATTR_PID, ctx->tgid); + if (ret < 0) + return -EINVAL; + + memcpy(ctx->comm, stats.ac_comm, TS_COMM_LEN); + + return 0; +} + +static const struct resource_control process_ctrls[] = { + { + .name = "PROCESS_CTRL_TGID", + .id = PROCESS_CTRL_TGID, + .ops = { + .set = process_setup_tgid, + }, + }, +}; + static int process_prepare_update(struct resource *res) { struct process_context *ctx = res->priv; @@ -449,7 +530,6 @@ static int process_prepare_update(struct resource *res) static int process_init(struct resource *res) { - struct taskstats stats; struct process_context *ctx; int ret; @@ -464,29 +544,12 @@ static int process_init(struct resource *res) if (!ctx) return -ENOMEM; - ctx->prev_total_time = get_total_cpu_time(); - ctx->pid = (pid_t)(intptr_t)res->user_data; - ret = kernel_get_memory_total(&ctx->total_memory); if (ret < 0) { free(ctx); return -EINVAL; } - /* update initial status */ - ret = update_taskstats(ctx); - if (ret < 0) { - free(ctx); - return -EINVAL; - } - - ret = query_taskstats(&stats, TASKSTATS_CMD_ATTR_PID, ctx->pid); - if (ret < 0) { - free(ctx); - return -EINVAL; - } - memcpy(ctx->comm, stats.ac_comm, TS_COMM_LEN); - res->priv = ctx; return 0; @@ -507,8 +570,9 @@ static const struct resource_driver process_resource_driver = { .name = "PROCESS", .type = RESOURCE_TYPE_PROCESS, .attrs = process_attrs, - .flags = RESOURCE_DRIVER_NO_DEVICE, .num_attrs = ARRAY_SIZE(process_attrs), + .ctrls = process_ctrls, + .num_ctrls = ARRAY_SIZE(process_ctrls), .ops = { .init = process_init, .exit = process_exit, diff --git a/src/resource/resource-system.c b/src/resource/resource-system.c index 2538ed0..e62b6d2 100644 --- a/src/resource/resource-system.c +++ b/src/resource/resource-system.c @@ -91,8 +91,7 @@ static int system_get_avg_cpu_util(const struct resource *res, util = __calculate_cpu_util(attr->id, &sysdata->prev_avg, &sysdata->curr_avg); if (util < 0) { - _W("failed to calculate average cpu util (%s.%d: %s)\n", - res->name, res->index, attr->name); + _W("failed to calculate average cpu util (%s: %s)\n", res->name, attr->name); util = 0; } *data = (void *)(intptr_t)util; @@ -132,8 +131,7 @@ static int system_get_per_cpu_util(const struct resource *res, &sysdata->prev_cpus[i], &sysdata->curr_cpus[i]); if (utils[i] < 0) { - _W("failed to calculate per-cpu util (%s.%d: %s)\n", - res->name, res->index, attr->name); + _W("failed to calculate per-cpu util (%s: %s)\n", res->name, attr->name); utils[i] = 0; } } @@ -238,8 +236,7 @@ static int system_driver_init(struct resource *res) ret = kernel_get_possible_cpu_num(); if (ret < 0) { - _I("failed to get possible cpu on system driver (%s.%d)\n", - res->name, res->index); + _I("failed to get possible cpu on system driver (%s)\n", res->name); goto err; } sysdata->num_possible_cpus = ret; @@ -247,8 +244,7 @@ static int system_driver_init(struct resource *res) sysdata->prev_cpus = calloc(sysdata->num_possible_cpus, sizeof(struct cpu_stat)); if (!sysdata->prev_cpus) { - _I("failed to allocate memory of prev_cpus (%s.%d)\n", - res->name, res->index); + _I("failed to allocate memory of prev_cpus (%s)\n", res->name); ret = -ENOMEM; goto err; } @@ -256,8 +252,7 @@ static int system_driver_init(struct resource *res) sysdata->curr_cpus = calloc(sysdata->num_possible_cpus, sizeof(struct cpu_stat)); if (!sysdata->curr_cpus) { - _I("failed to allocate memory of curr_cpus (%s.%d)\n", - res->name, res->index); + _I("failed to allocate memory of curr_cpus (%s)\n", res->name); ret = -ENOMEM; goto err_prev_cpus; } @@ -296,8 +291,7 @@ static int system_driver_prepare_update(struct resource *res) memcpy(&sysdata->prev_avg, &sysdata->curr_avg, sizeof(sysdata->prev_avg)); ret = kernel_get_total_cpu_stat(&sysdata->curr_avg); if (ret < 0) { - _I("failed to calculate average cpu util (%s:%d)\n", - res->name, res->index); + _I("failed to calculate average cpu util (%s)\n", res->name); return ret; } @@ -308,8 +302,7 @@ static int system_driver_prepare_update(struct resource *res) sysdata->num_possible_cpus, &sysdata->num_online_cpus); if (ret < 0) { - _I("failed to calculate per-cpu util (%s:%d)\n", - res->name, res->index); + _I("failed to calculate per-cpu util (%s)\n", res->name); return ret; } @@ -321,7 +314,6 @@ static const struct resource_driver system_resource_driver = { .type = RESOURCE_TYPE_SYSTEM, .attrs = system_attrs, .num_attrs = ARRAY_SIZE(system_attrs), - .flags = RESOURCE_DRIVER_NO_DEVICE, .ops = { .init = system_driver_init, .exit = system_driver_exit, diff --git a/src/util/resource.c b/src/util/resource.c index fc342f4..fd14ec4 100644 --- a/src/util/resource.c +++ b/src/util/resource.c @@ -24,7 +24,9 @@ #include #define RESOURCE_ATTR_MASK (ULLONG_MAX) -#define RESOURCE_ATTR_INDEX(id) (63 - __builtin_clzll(id)) +#define BIT64_INDEX(id) (63 - __builtin_clzll(id)) +#define RESOURCE_ATTR_INDEX(id) BIT64_INDEX(id) +#define RESOURCE_CTRL_INDEX(id) BIT64_INDEX(id) static GList *g_resource_driver_head; static GList *g_resource_device_head; @@ -153,10 +155,8 @@ void delete_resource(struct resource *resource) do_delete_resource(resource); } -struct resource *create_resource(int resource_type, int resource_index, - void *user_data) +struct resource *create_resource(int resource_type) { - const struct resource_device *device = NULL; const struct resource_driver *driver = NULL; struct resource *resource = NULL; int i, ret; @@ -165,30 +165,13 @@ struct resource *create_resource(int resource_type, int resource_index, if (!driver) return NULL; - if (!(driver->flags & RESOURCE_DRIVER_NO_DEVICE)) { - device = find_resource_device(resource_type, resource_index); - if (!device) { - _E("Not available resource: type: %d, index: %d\n", - resource_type, resource_index); - return NULL; - } - } - resource = calloc(1, sizeof(*resource)); if (!resource) return NULL; - if (device) { - resource->type = device->type; - resource->name = g_strdup(device->name); - resource->index = device->index; - } else { - resource->type = resource_type; - resource->name = g_strdup(driver->name); - resource->index = resource_index; - } + resource->type = resource_type; + resource->name = g_strdup(driver->name); resource->driver = driver; - resource->user_data = user_data; resource->num_attrs = driver->num_attrs; resource->attrs = driver->attrs; resource->attrs_value = calloc(resource->num_attrs, @@ -201,6 +184,9 @@ struct resource *create_resource(int resource_type, int resource_index, for (i = 0; i < resource->num_attrs; i++) resource->attrs_value[i].type = driver->attrs[i].type; + resource->ctrls = driver->ctrls; + resource->num_ctrls = driver->num_ctrls; + if (driver->ops.init) { ret = driver->ops.init(resource); if (ret < 0) { @@ -212,6 +198,26 @@ struct resource *create_resource(int resource_type, int resource_index, return resource; } +int set_resource_control(struct resource *resource, u_int64_t ctrl_id, const void *data) +{ + const struct resource_control *ctrl; + int ctrl_index = RESOURCE_CTRL_INDEX(ctrl_id); + int ret; + + if (!resource) + return -EINVAL; + + ctrl = &resource->ctrls[ctrl_index]; + if (!ctrl->ops.set) + return -ENOTSUP; + + ret = ctrl->ops.set(resource, ctrl, data); + if (ret < 0) + return ret; + + return 0; +} + static int update_resource_attr(struct resource *resource, u_int64_t attr_id) { int attr_index = RESOURCE_ATTR_INDEX(attr_id);