pass: resmon: Use monitor id to identify timer instead of monitor type 77/269977/4
authorChanwoo Choi <cw00.choi@samsung.com>
Wed, 12 Jan 2022 06:36:50 +0000 (15:36 +0900)
committerChanwoo Choi <cw00.choi@samsung.com>
Mon, 24 Jan 2022 09:23:58 +0000 (18:23 +0900)
Support that a pass_resource can register the multiple timers with same
monitor type. If use monitor type as ID, a pass_resource is not able
to use the one more timers with same monitor type. It is wrong
registration.

Change-Id: I8e0d24fe038039076bbd8a9cd47b3dedd54913c5
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
src/pass/pass-cpuhp.c
src/pass/pass-resmon-internal.h
src/pass/pass-resmon.c
src/pass/pass-resmon.h
src/pass/pass-thermal.c
src/pass/pass.h

index 7aaadb9..15f36a7 100644 (file)
@@ -210,7 +210,7 @@ static int cpuhp_timer_func(void *result, void *user_data)
                                curr_gov_timeout,
                                next_gov_timeout);
 
-               pass_resmon_update_timer_interval(res, RESMON_SRC_CPUHP,
+               pass_resmon_update_timer_interval(res, cpuhp->timer_id,
                                                next_gov_timeout * 1000);
        }
 
@@ -247,6 +247,7 @@ static void cpuhp_governor_start(struct pass_resource *res)
                _E("failed to register timer for CPUHP\n");
                return;
        }
+       cpuhp->timer_id = ret;
 
        /* Set PASS state as PASS_ON */
        cpuhp->state = PASS_ON;
@@ -272,7 +273,7 @@ static void cpuhp_governor_stop(struct pass_resource *res)
        }
 
        /* Unregister the resource-monitor for CPUHP module */
-       pass_resmon_unregister_timer(res, RESMON_SRC_CPUHP);
+       pass_resmon_unregister_timer(res, cpuhp->timer_id);
 
        /* Set PASS state as PASS_OFF */
        cpuhp->state = PASS_OFF;
index 80a4e79..82f5bbf 100644 (file)
@@ -92,6 +92,9 @@ struct resmon {
        /** Resource Monitor's source type */
        enum resmon_src_type src_type;
 
+       /* Resource Monitor's ID */
+       guint id;
+
        /**
         * User callback function when following event happen:
         * - In case of timer-baed resmon, the timer is expired.
@@ -116,11 +119,6 @@ struct resmon {
         * timer-based resource monitor.
         */
        unsigned int timer_interval;
-       /**
-        * Timer ID. It will be only used for
-        * timer-based resource monitor.
-        */
-       guint timer_id;
 
        /**
         * Type of uevent-based resource monitor. It will be only used for
index d1931ee..0ebfe11 100644 (file)
@@ -59,44 +59,30 @@ static int g_udev_count = 0;
 
 extern struct resmon_ops *resmon_get_ops(enum resmon_src_type src_type);
 
-static bool resmon_is_created(struct pass_resmon *resmon,
-                                       enum resmon_type type,
-                                       enum resmon_src_type src_type)
-{
-       switch (type) {
-       case RESMON_TIMER:
-               return !!(resmon->timer_state & src_type);
-       case RESMON_UEVENT:
-               return !!(resmon->uevent_state & src_type);
-       default:
-               return false;
-       }
-}
-
-static gint __compare_monitor_type(gconstpointer data, gconstpointer input)
+static gint __compare_monitor_id(gconstpointer data, gconstpointer input)
 {
        struct resmon *monitor = (struct resmon *)data;
-       enum resmon_src_type *src_type = (enum resmon_src_type *)input;
+       guint id = *(guint *)input;
 
-       if (monitor->src_type == *src_type)
+       if (monitor->id == id)
                return 0;
        return -1;
 }
 
 static struct resmon *resmon_find_monitor(struct pass_resmon *resmon,
                                        enum resmon_type type,
-                                       enum resmon_src_type src_type)
+                                       guint id)
 {
        GList *node;
 
        switch (type) {
        case RESMON_TIMER:
-               node = g_list_find_custom(resmon->timer_list, &src_type,
-                                               __compare_monitor_type);
+               node = g_list_find_custom(resmon->timer_list, &id,
+                                               __compare_monitor_id);
                break;
        case RESMON_UEVENT:
-               node = g_list_find_custom(resmon->uevent_list, &src_type,
-                                               __compare_monitor_type);
+               node = g_list_find_custom(resmon->uevent_list, &id,
+                                               __compare_monitor_id);
                break;
        default:
                return NULL;
@@ -121,18 +107,18 @@ static int resmon_timer_add(struct resmon *monitor, unsigned int interval)
        int ret;
 
        /* Add new timer-based resmon to timer_list */
-       if (!resmon_is_created(resmon, RESMON_TIMER, monitor->src_type)) {
-               monitor->timer_id = g_timeout_add((guint)interval,
+       if (!resmon_find_monitor(resmon, RESMON_TIMER, monitor->id)) {
+               monitor->id = g_timeout_add((guint)interval,
                                        (GSourceFunc)resmon_timer_func,
                                        (gpointer)monitor);
-               if (!monitor->timer_id)
+               if (!monitor->id)
                        return -EPERM;
                monitor->timer_interval = interval;
 
                if (monitor->ops && monitor->ops->init) {
                        ret = monitor->ops->init(monitor);
                        if (ret < 0) {
-                               g_source_remove(monitor->timer_id);
+                               g_source_remove(monitor->id);
                                monitor->timer_interval = 0;
                                return ret;
                        }
@@ -140,23 +126,22 @@ static int resmon_timer_add(struct resmon *monitor, unsigned int interval)
 
                resmon->timer_list = g_list_append(resmon->timer_list,
                                                (gpointer)monitor);
-               resmon->timer_state |= monitor->src_type;
 
        /* Update timer interval of the registered timer-based resmon */
        } else {
-               g_source_remove(monitor->timer_id);
+               g_source_remove(monitor->id);
                monitor->timer_interval = 0;
 
                /* Update timer interval of timer-based resmon */
-               monitor->timer_id = g_timeout_add((guint)interval,
+               monitor->id = g_timeout_add((guint)interval,
                                        (GSourceFunc)resmon_timer_func,
                                        (gpointer)monitor);
-               if (!monitor->timer_id)
+               if (!monitor->id)
                        return -EPERM;
                monitor->timer_interval = interval;
        }
 
-       return 0;
+       return monitor->id;
 }
 
 /**
@@ -169,7 +154,7 @@ static int resmon_timer_delete(struct resmon *monitor)
        struct pass_resmon *resmon = monitor->resmon;
        int ret;
 
-       g_source_remove(monitor->timer_id);
+       g_source_remove(monitor->id);
 
        if (monitor->ops && monitor->ops->exit) {
                ret = monitor->ops->exit(monitor);
@@ -177,7 +162,6 @@ static int resmon_timer_delete(struct resmon *monitor)
                        return ret;
        }
 
-       resmon->timer_state &= ~(monitor->src_type);
        resmon->timer_list = g_list_remove(resmon->timer_list,
                                        (gpointer)monitor);
 
@@ -243,15 +227,14 @@ static gboolean resmon_timer_func(gpointer data)
        return true;
 }
 
-void *pass_resmon_get_result(struct pass_resource *res,
-                            enum resmon_src_type src_type)
+void *pass_resmon_get_result(struct pass_resource *res, guint id)
 {
        struct resmon *monitor;
 
        if (!res)
                return NULL;
 
-       monitor = resmon_find_monitor(&res->resmon, RESMON_TIMER, src_type);
+       monitor = resmon_find_monitor(&res->resmon, RESMON_TIMER, id);
        if (!monitor)
                return NULL;
 
@@ -266,7 +249,7 @@ void *pass_resmon_get_result(struct pass_resource *res,
  * @param      [in] timer_interval Interval of timer (unit: millisecond)
  * @param      [in] user_func Callback function pointer when timer is expired
  * @param      [in] user_data The passed user user_data.
- * @return     @c 0 on success, otherwise error value
+ * @return     @c id with positive integer on success, otherwise error value
  */
 int pass_resmon_register_timer(struct pass_resource *res,
                                enum resmon_src_type src_type,
@@ -280,19 +263,12 @@ int pass_resmon_register_timer(struct pass_resource *res,
        int res_type;
        int ret;
 
-       if (!res || src_type == 0 || timer_type == 0 || user_func == NULL)
+       if (!res || timer_type == 0 || user_func == NULL)
                return -EINVAL;
 
        resmon = &res->resmon;
        res_type = res->config_data.res_type;
 
-       /* Prevent the monitoring of already required type */
-       if (resmon_is_created(resmon, RESMON_TIMER, src_type)) {
-               _E("timer is already created (res_type: %d, src_type: 0x%x)\n",
-                                               res_type, src_type);
-               return -EBUSY;
-       }
-
        /* Allocate the memory for resource monitor */
        monitor = calloc(1, sizeof(struct resmon));
        if (!monitor)
@@ -316,7 +292,7 @@ int pass_resmon_register_timer(struct pass_resource *res,
                goto err;
        }
 
-       return 0;
+       return monitor->id;
 
 err:
        free(monitor);
@@ -328,30 +304,29 @@ err:
 /**
  * @brief      Unregister a timer-based resource monitor
  * @param      [in] res Instance of a resource monitor
- * @param      [in] src_type Type of resource monitor source
+ * @param      [in] id ID of resource monitor
  * @return     @c 0 on success, otherwise error value
  */
-int pass_resmon_unregister_timer(struct pass_resource *res,
-                               enum resmon_src_type src_type)
+int pass_resmon_unregister_timer(struct pass_resource *res, guint id)
 {
        struct resmon *monitor;
        int ret;
 
-       if (!res || src_type == 0)
+       if (!res || id == 0)
                return -EINVAL;
 
-       monitor = resmon_find_monitor(&res->resmon, RESMON_TIMER, src_type);
+       monitor = resmon_find_monitor(&res->resmon, RESMON_TIMER, id);
        if (!monitor) {
-               _E("failed to find monitor (res_type: %d, src_type: 0x%x)\n",
-                                       res->config_data.res_type, src_type);
+               _E("failed to find monitor (res_type: %d, id: %d)\n",
+                                       res->config_data.res_type, id);
                return -EINVAL;
        }
 
        /* Delete timer-based resource monitor */
        ret = resmon_timer_delete(monitor);
        if (ret < 0) {
-               _E("failed to delete monitor (res_type: %d, src_type: 0x%x)\n",
-                                       res->config_data.res_type, src_type);
+               _E("failed to delete monitor (res_type: %d, id: %d)\n",
+                                       res->config_data.res_type, id);
        }
 
        return 0;
@@ -360,13 +335,13 @@ int pass_resmon_unregister_timer(struct pass_resource *res,
 /**
  * @brief      Update the interval of timer
  * @param      [in] res Instance of a resource monitor
- * @param      [in] src_type Type of resource monitor source
+ * @param      [in] id ID of resource monitor
  * @param      [in] timer_interval Interval of timer-based resource monitor
  *             (unit: millisecond)
  * @return     @c 0 on success, otherwise error value
  */
 int pass_resmon_update_timer_interval(struct pass_resource *res,
-                               enum resmon_src_type src_type,
+                               guint id,
                                int timer_interval)
 {
        struct resmon *monitor;
@@ -376,10 +351,10 @@ int pass_resmon_update_timer_interval(struct pass_resource *res,
                return -EINVAL;
 
        /* Find registered timer-based resmon */
-       monitor = resmon_find_monitor(&res->resmon, RESMON_TIMER, src_type);
+       monitor = resmon_find_monitor(&res->resmon, RESMON_TIMER, id);
        if (!monitor) {
-               _E("failed to find monitor (res_type:%d, src_type: 0x%x)\n",
-                               res->config_data.res_type, src_type);
+               _E("failed to find monitor (res_type:%d, id: %d)\n",
+                               res->config_data.res_type, id);
                return -EINVAL;
        }
 
@@ -391,7 +366,7 @@ int pass_resmon_update_timer_interval(struct pass_resource *res,
        if (ret < 0)
                return -EINVAL;
 
-       return 0;
+       return monitor->id;
 }
 
 /**
@@ -450,6 +425,7 @@ out:
  */
 static int resmon_uevent_add(struct resmon *monitor)
 {
+       static int uevent_id = 0;
        struct udev_monitor *udev_monitor;
        struct pass_resmon *resmon = monitor->resmon;
        struct pass_resource *res
@@ -558,10 +534,10 @@ static int resmon_uevent_add(struct resmon *monitor)
        /* Add new uevent-based resmon to uevent_list */
        resmon->uevent_list = g_list_append(resmon->uevent_list,
                                                (gpointer)monitor);
-       resmon->uevent_state |= monitor->src_type;
 
        monitor->udev_monitor = udev_monitor;;
        monitor->udev_monitor_fd = gfd;
+       monitor->id = ++uevent_id;
 
        return 0;
 
@@ -604,7 +580,6 @@ static int resmon_uevent_delete(struct resmon *monitor)
        monitor->udev_monitor_fd = -1;
 
        /* Delete the uevent-based resmon from uevent_list */
-       resmon->uevent_state &= ~(monitor->src_type);
        resmon->uevent_list = g_list_remove(resmon->uevent_list,
                                                (gpointer)monitor);
 
@@ -628,21 +603,13 @@ int pass_resmon_register_uevent(struct pass_resource *res,
        struct resmon *monitor;
        int ret;
 
-       if (!res || src_type == 0 || user_func == NULL) {
+       if (!res || user_func == NULL) {
                _E("invalid parameter\n");
                return -EINVAL;
        }
 
        resmon = &res->resmon;
 
-       /* Prevent the monitoring of already required type */
-       if (resmon_is_created(resmon, RESMON_UEVENT, src_type)) {
-               _E("uevent-based resmon is already created "\
-                                       "(res_name: %s, src_type: 0x%x)\n",
-                                       res->config_data.res_name, src_type);
-               return -EBUSY;
-       }
-
        /* Allocate the memory for resource monitor */
        monitor = calloc(1, sizeof(struct resmon));
        if (!monitor)
@@ -664,7 +631,7 @@ int pass_resmon_register_uevent(struct pass_resource *res,
                goto err;
        }
 
-       return 0;
+       return monitor->id;
 
 err:
        free(monitor);
@@ -676,32 +643,31 @@ err:
 /**
  * @brief      Unregister an uevent-based resource monitor.
  * @param      [in] res Instance of a resource monitor
- * @param      [in] src_type Type of resource monitor source
+ * @param      [in] id ID of resource monitor
  * @return     @c 0 on success, otherwise error value
  */
-int pass_resmon_unregister_uevent(struct pass_resource *res,
-                               enum resmon_src_type src_type)
+int pass_resmon_unregister_uevent(struct pass_resource *res, guint id)
 {
        struct resmon *monitor;
        int ret;
 
-       if (!res || src_type == 0) {
+       if (!res || id == 0) {
                _E("invalid parameter\n");
                return -EINVAL;
        }
 
-       monitor = resmon_find_monitor(&res->resmon, RESMON_UEVENT, src_type);
+       monitor = resmon_find_monitor(&res->resmon, RESMON_UEVENT, id);
        if (!monitor) {
-               _E("failed to find monitor (res_name: %s, type: 0x%x)\n",
-                                       res->config_data.res_name, src_type);
+               _E("failed to find monitor (res_name: %s, type: %d)\n",
+                                       res->config_data.res_name, id);
                return -EINVAL;
        }
 
        /* Delete uevent-based resource monitor */
        ret = resmon_uevent_delete(monitor);
        if (ret < 0) {
-               _E("failed to delete monitor (res_name: %s, type: 0x%x)\n",
-                                       res->config_data.res_name, src_type);
+               _E("failed to delete monitor (res_name: %s, type: %d)\n",
+                                       res->config_data.res_name, id);
        }
 
        /* Free the memory of resource monitor */
@@ -729,11 +695,9 @@ int pass_resmon_init(struct pass_resource *res)
        resmon = &res->resmon;
 
        resmon->timer_list = NULL;
-       resmon->timer_state = 0;
 
        /* Initialize the uevent-related variables */
        resmon->uevent_list = NULL;
-       resmon->uevent_state = 0;
 
        if (g_udev_count == 0) {
                g_udev = udev_new();
@@ -769,12 +733,10 @@ int pass_resmon_exit(struct pass_resource *res)
 
        g_list_free(resmon->timer_list);
        resmon->timer_list = NULL;
-       resmon->timer_state = 0;
 
        /* Free the uevent-related variables */
        g_list_free(resmon->uevent_list);
        resmon->uevent_list = NULL;
-       resmon->uevent_state = 0;
 
        udev_unref(g_udev);
        g_udev_count--;
index 3992a31..f6c88e4 100644 (file)
@@ -109,8 +109,7 @@ struct resmon_result_src_cpuhp {
        unsigned int avg_thread_runnable_load;
 };
 
-void *pass_resmon_get_result(struct pass_resource *res,
-                            enum resmon_src_type src_type);
+void *pass_resmon_get_result(struct pass_resource *res, guint timer_id);
 
 /*
  * pass_resmon_register_timer - Register timer-based resource monitor.
@@ -133,21 +132,19 @@ int pass_resmon_register_timer(struct pass_resource *res,
  * pass_resmon_unregister_timer - Unregister timer-based resource monitor.
  *
  * @res: the instance of struct pass_resource.
- * @src_type: the type of resource monitor among 'enum resmon_src_type'.
+ * @timer_id: Timer ID of resource monitor source
  */
-int pass_resmon_unregister_timer(struct pass_resource *res,
-                               enum resmon_src_type src_type);
+int pass_resmon_unregister_timer(struct pass_resource *res, guint timer_id);
 
 /*
  * pass_resmon_update_timer_interval - Update interval of timer-based monitor.
  *
  * @res: the instance of struct pass_resource.
- * @src_type: the type of resource monitor among 'enum resmon_src_type'.
+ * @timer_id: Timer ID of resource monitor source
  * @timer_interval: the interval of timer (unit: millisecond).
  */
 int pass_resmon_update_timer_interval(struct pass_resource *res,
-                               enum resmon_src_type src_type,
-                               int timer_interval);
+                               guint timer_id, int timer_interval);
 
 /*
  * pass_resmon_register_uevent - Register uevent-based resource monitor
index 0d5517c..db19eea 100644 (file)
@@ -45,6 +45,7 @@ static int thermal_update(struct pass_resource *res,
        int new_temp, prev_temp;
        int i, new_scenario_idx;
        int ret;
+       int timer_id;
 
        if (!res || !thermal_result) {
                _E("invalid parameter for thermal monitor\n");
@@ -97,13 +98,14 @@ static int thermal_update(struct pass_resource *res,
        if (new_timer_interval < 0)
                new_timer_interval = res->thermal.timer_interval;
 
-       ret = pass_resmon_update_timer_interval(res, RESMON_SRC_THERMAL,
+       timer_id = pass_resmon_update_timer_interval(res, res->thermal.timer_id,
                                new_timer_interval);
-       if (ret < 0) {
+       if (timer_id < 0) {
                _W("failed to update interval of timer-based monitor " \
                        "(res_name:%s, src_type: 0x%x)\n",
                        res->config_data.res_name, RESMON_SRC_THERMAL);
        }
+       thermal->timer_id = timer_id;
 
        /* Update thermal information of each h/w resource */
        thermal->curr_temp = new_temp;
@@ -248,7 +250,7 @@ static int thermal_get_scenario(void *data, void *user_data)
        int ret;
 
        /* Get thermal_result raw data by reading directly */
-       thermal_result = pass_resmon_get_result(res, RESMON_SRC_THERMAL);
+       thermal_result = pass_resmon_get_result(res, res->thermal.timer_id);
 
        /*
         * Update thermal scenario by using both the monitored raw data
@@ -270,6 +272,7 @@ static int thermal_get_scenario(void *data, void *user_data)
 int pass_thermal_init(struct pass_resource *res)
 {
        int ret;
+       int timer_id, uevent_id;
 
        if (!res)
                return -EINVAL;
@@ -283,25 +286,27 @@ int pass_thermal_init(struct pass_resource *res)
         * update the timer interval with the required value
         * after first monitoring is finished.
         */
-       ret = pass_resmon_register_timer(res, RESMON_SRC_THERMAL,
+       timer_id = pass_resmon_register_timer(res, RESMON_SRC_THERMAL,
                        RESMON_TIMER_PERIODIC, 1000,
                        thermal_monitor_func, res);
-       if (ret < 0) {
+       if (timer_id < 0) {
                _E("failed to register timer-based monitor " \
                        "(res_name:%s, src_type: 0x%x)\n",
                        res->config_data.res_name, RESMON_SRC_THERMAL);
                return -EINVAL;
        }
+       res->thermal.timer_id = timer_id;
 
        /* Register uevent-based resource monitor to monitor thermal info. */
-       ret = pass_resmon_register_uevent(res, RESMON_SRC_THERMAL,
+       uevent_id = pass_resmon_register_uevent(res, RESMON_SRC_THERMAL,
                        thermal_monitor_func, res);
-       if (ret < 0) {
+       if (uevent_id < 0) {
                _E("failed to register uevent-based monitor " \
                        "(res_name:%s, src_type: 0x%x)\n",
                        res->config_data.res_name, RESMON_SRC_THERMAL);
                goto err_timer;
        }
+       res->thermal.uevent_id = uevent_id;
 
        /* Initialize the default scenario index */
        res->thermal.curr_scenario_idx = -1;
@@ -317,12 +322,12 @@ int pass_thermal_init(struct pass_resource *res)
        return 0;
 
 err_uevent:
-       ret = pass_resmon_unregister_uevent(res, RESMON_SRC_THERMAL);
+       ret = pass_resmon_unregister_uevent(res, uevent_id);
        if (ret < 0)
                _E("failed to unregister uevent-based monitor\n");
 
 err_timer:
-       ret = pass_resmon_unregister_timer(res, RESMON_SRC_THERMAL);
+       ret = pass_resmon_unregister_timer(res, timer_id);
        if (ret < 0) {
                _E("failed to unregister timer-based monitor " \
                        "(res_name:%s, src_type: 0x%x)\n",
@@ -351,18 +356,18 @@ int pass_thermal_exit(struct pass_resource *res)
        if (ret < 0)
                _E("failed to unregister a notifier callback\n");
 
-       ret = pass_resmon_unregister_uevent(res, RESMON_SRC_THERMAL);
+       ret = pass_resmon_unregister_uevent(res, res->thermal.uevent_id);
        if (ret < 0) {
                _E("failed to unregister uevent-based monitor " \
-                       "(res_name:%s, src_type: 0x%x)\n",
-                       res->config_data.res_name, RESMON_SRC_THERMAL);
+                       "(res_name:%s, uevent_id:%d)\n",
+                       res->config_data.res_name, res->thermal.uevent_id);
        }
 
-       ret = pass_resmon_unregister_timer(res, RESMON_SRC_THERMAL);
+       ret = pass_resmon_unregister_timer(res, res->thermal.timer_id);
        if (ret < 0) {
                _E("failed to unregister timer-based monitor " \
-                       "(res_name:%s, src_type: 0x%x)\n",
-                       res->config_data.res_name, RESMON_SRC_THERMAL);
+                       "(res_name:%s, timer_id:%d)\n",
+                       res->config_data.res_name, res->thermal.timer_id);
        }
 
        /* Initialize the default scenario index */
index f99e2de..e9795d8 100644 (file)
@@ -335,13 +335,9 @@ struct pass_resmon {
 
        /** List of required timer-based resource monitor */
        GList *timer_list;
-       /** State of all timer-based resource-monitor */
-       uint64 timer_state;
 
        /** List of required uevent-based resource monitor */
        GList *uevent_list;
-       /** State of all uevent-based resource monitor */
-       uint64 uevent_state;
 };
 
 /**
@@ -377,6 +373,9 @@ struct pass_cpuhp {
        /** State of PASS_MODULE_CPUHP */
        enum pass_state state;
 
+       /** ID of timer-based monitor */
+       int timer_id;
+
        /** Threshold used when decide whether CPU is busy or not */
        unsigned int pass_cpu_threshold;
        /** Threshold used when increasing the pass_level */
@@ -409,6 +408,11 @@ struct pass_thermal {
 
        /** Interval of timer-based monitor (unit: millisecond) */
        unsigned int timer_interval;
+       /** ID of timer-based monitor */
+       int timer_id;
+       /** ID of uevent-based monitor */
+       int uevent_id;
+
        /** Index of current thermal scenario */
        int curr_scenario_idx;
        /** Index of previous thermal scenario */