On Tue, Aug 22, 2017 at 01:15:33PM +0300, Manos Pitsidianakis wrote:
> /* Increments the reference count of a ThrottleGroup given its name.
> *
> * If no ThrottleGroup is found with the given name a new one is
> * created.
> *
> + * This function edits throttle_groups and must be called under the global
> + * mutex.
> + *
> * @name: the name of the ThrottleGroup
> * @ret: the ThrottleState member of the ThrottleGroup
> */
> ThrottleState *throttle_group_incref(const char *name)
> {
> ThrottleGroup *tg = NULL;
> - ThrottleGroup *iter;
> -
> - qemu_mutex_lock(&throttle_groups_lock);
>
> /* Look for an existing group with that name */
> - QTAILQ_FOREACH(iter, &throttle_groups, list) {
> - if (!strcmp(name, iter->name)) {
> - tg = iter;
> - break;
> - }
> - }
> + tg = throttle_group_by_name(name);
>
> - /* Create a new one if not found */
> - if (!tg) {
> - tg = g_new0(ThrottleGroup, 1);
> + if (tg) {
> + object_ref(OBJECT(tg));
> + } else {
> + /* Create a new one if not found */
> + /* new ThrottleGroup obj will have a refcnt = 1 */
> + tg = THROTTLE_GROUP(object_new(TYPE_THROTTLE_GROUP));
> tg->name = g_strdup(name);
> - tg->clock_type = QEMU_CLOCK_REALTIME;
> -
> - if (qtest_enabled()) {
> - /* For testing block IO throttling only */
> - tg->clock_type = QEMU_CLOCK_VIRTUAL;
> - }
> - qemu_mutex_init(&tg->lock);
> - throttle_init(&tg->ts);
> - QLIST_INIT(&tg->head);
> -
> - QTAILQ_INSERT_TAIL(&throttle_groups, tg, list);
This is where the ThrottleGroup needs to be added to the QOM tree:
object_property_add_child(object_get_objects_root(),
id, obj, &local_err);
> + throttle_group_obj_complete((UserCreatable *)tg, &error_abort);
This cast is risky - if UserCreatable ever adds fields it can break.
Please use a QOM cast: USER_CREATABLE(tg). It uses the type information
and finds the interface.
> +static ThrottleParamInfo properties[] = {
This array can be const.
> +{
Missing indentation. Seems unusual but I guess you're trying to avoid
reaching 80 chars? If checkpatch.pl doesn't complain then you can get
away with it but normal indentation would be best.
> + switch (info->category) {
> + case AVG:
> + cfg.buckets[info->type].avg = value;
> + break;
> + case MAX:
> + cfg.buckets[info->type].max = value;
> + break;
> + case BURST_LENGTH:
> + if (value > UINT_MAX) {
> + error_setg(&local_err, "%s value must be in the"
> + "range [0, %u]", info->name, UINT_MAX);
> + goto ret;
> + }
> + cfg.buckets[info->type].burst_length = value;
> + break;
> + case IOPS_SIZE:
> + cfg.op_size = value;
> + }
Please use break statements even for the last case. If another case is
added later it might accidentally fall through without a break
statement.