Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932262AbcCQX1e (ORCPT ); Thu, 17 Mar 2016 19:27:34 -0400 Received: from LGEAMRELO11.lge.com ([156.147.23.51]:56281 "EHLO lgeamrelo11.lge.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751031AbcCQX10 (ORCPT ); Thu, 17 Mar 2016 19:27:26 -0400 X-Original-SENDERIP: 156.147.1.125 X-Original-MAILFROM: namhyung@kernel.org X-Original-SENDERIP: 165.244.98.204 X-Original-MAILFROM: namhyung@kernel.org X-Original-SENDERIP: 10.177.227.17 X-Original-MAILFROM: namhyung@kernel.org Date: Fri, 18 Mar 2016 08:27:22 +0900 From: Namhyung Kim To: Taeung Song CC: Arnaldo Carvalho de Melo , linux-kernel@vger.kernel.org, Jiri Olsa , Ingo Molnar , Peter Zijlstra Subject: Re: [PATCH v2 1/5] perf config: Introduce perf_config_set class Message-ID: <20160317232722.GC5194@sejong> References: <1457957769-3700-1-git-send-email-treeze.taeung@gmail.com> <1457957769-3700-2-git-send-email-treeze.taeung@gmail.com> <20160317123157.GA1670@danjae.kornet> <56EABAC4.107@gmail.com> MIME-Version: 1.0 In-Reply-To: <56EABAC4.107@gmail.com> User-Agent: Mutt/1.5.24 (2015-08-30) X-MIMETrack: Itemize by SMTP Server on LGEKRMHUB06/LGE/LG Group(Release 8.5.3FP6|November 21, 2013) at 2016/03/18 08:27:22, Serialize by Router on LGEKRMHUB06/LGE/LG Group(Release 8.5.3FP6|November 21, 2013) at 2016/03/18 08:27:22, Serialize complete at 2016/03/18 08:27:22 Content-Type: text/plain; charset="utf-8" Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5804 Lines: 210 On Thu, Mar 17, 2016 at 11:10:12PM +0900, Taeung Song wrote: > Hi, Namhyung > > On 03/17/2016 09:31 PM, Namhyung Kim wrote: > >Hi Taeung, > > > >On Mon, Mar 14, 2016 at 09:16:05PM +0900, Taeung Song wrote: > >>This infrastructure code was designed for > >>upcoming features of perf-config. > >> > >>That collect config key-value pairs from user and > >>system config files (i.e. user wide ~/.perfconfig > >>and system wide $(sysconfdir)/perfconfig) > >>to manage perf's configs. > >> > >>Cc: Namhyung Kim > >>Cc: Jiri Olsa > >>Signed-off-by: Taeung Song > >>--- > >> tools/perf/builtin-config.c | 1 + > >> tools/perf/util/config.c | 123 ++++++++++++++++++++++++++++++++++++++++++++ > >> tools/perf/util/config.h | 21 ++++++++ > >> 3 files changed, 145 insertions(+) > >> create mode 100644 tools/perf/util/config.h > >> > >>diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c > >>index c42448e..412c725 100644 > >>--- a/tools/perf/builtin-config.c > >>+++ b/tools/perf/builtin-config.c > >>@@ -12,6 +12,7 @@ > >> #include > >> #include "util/util.h" > >> #include "util/debug.h" > >>+#include "util/config.h" > >> > >> static bool use_system_config, use_user_config; > >> > >>diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c > >>index 4e72763..b9660e4 100644 > >>--- a/tools/perf/util/config.c > >>+++ b/tools/perf/util/config.c > >>@@ -13,6 +13,7 @@ > >> #include > >> #include "util/hist.h" /* perf_hist_config */ > >> #include "util/llvm-utils.h" /* perf_llvm_config */ > >>+#include "config.h" > >> > >> #define MAXNAME (256) > >> > >>@@ -506,6 +507,128 @@ out: > >> return ret; > >> } > >> > >>+static struct perf_config_item *find_config(struct list_head *config_list, > >>+ const char *section, > >>+ const char *name) > >>+{ > >>+ struct perf_config_item *config; > >>+ > >>+ list_for_each_entry(config, config_list, list) { > >>+ if (!strcmp(config->section, section) && > >>+ !strcmp(config->name, name)) > >>+ return config; > >>+ } > > > >Hmm.. why do you remove the section list? > > > > IMHO, there are several reasons > > 1) To use only one list (default config, custom config(user/system)) > > 1-1) I used two list that were 'list_head sections' > and 'config_item default_configs[]'. So if checking > type of config variable, two for-loop must be needed > for each list. Because two structure was different i.e. > > 'sections' list mean config_section list > that each section contain config_element list. > (there wasn't telling about correct type of 'value' instead of string(char > *)) > > struct config_element { > char *name; > char *value; > struct list_head list; > }; > > struct config_section { > char *name; > struct list_head element_head; > struct list_head list; > }; > > 'struct config_item default_configs[]' mean all default configs. > > struct config_item { > const char *section; > const char *name; > union { > bool b; > int i; > u32 l; > u64 ll; > float f; > double d; > const char *s; > } value; > enum config_type type; > const char *desc; > }; > > > IMHO, I think this is a bit complex > and I want to simplify the perf's config list on perf-config. > > 2) A small number of perf's configs > > I think perf's configs aren't too many so I think > two structure for section and element aren't needed. OK. > > 3) A object for a config variable need to have enough info for itself > > This is a bit similar to 1) reason. > If using only 'struct config_item' for the config list, > it can contain section name, name, values(default, user config, > system config, both config), correct type, etc. > > If we do, we needn't to find detail for a config variable at other objects > e.g. > When we find correct type of a config variable, > we needn't to do for-loop for default_configs[] in order to know the > type. I'm not sure I understand you correctly, but I think this is not related to the two-level structure. > > > I think this is better than old two structure. > > >>+ > >>+ return NULL; > >>+} > >>+ > >>+static struct perf_config_item *add_config(struct list_head *config_list, > >>+ const char *section, > >>+ const char *name) > >>+{ > >>+ struct perf_config_item *config = zalloc(sizeof(*config)); > >>+ > >>+ if (!config) > >>+ return NULL; > >>+ > >>+ config->section = strdup(section); > >>+ if (!section) > >>+ goto out_err; > >>+ > >>+ config->name = strdup(name); > >>+ if (!name) { > >>+ free((char *)config->section); > >>+ goto out_err; > >>+ } > >>+ > >>+ list_add_tail(&config->list, config_list); > >>+ return config; > >>+ > >>+out_err: > >>+ free(config); > >>+ pr_err("%s: strdup failed\n", __func__); > >>+ return NULL; > >>+} > >>+ > >>+static int set_value(struct perf_config_item *config, const char *value) > >>+{ > >>+ char *val = strdup(value); > >>+ > >>+ if (!val) > >>+ return -1; > >>+ config->value = val; > > > >It seems to overwrite old value.. > > > > Yes, I know it. > If don't using '--user' or '--system', > there isn't exclusive config file path > then have to read both config files. > > But because user config file has a high order of priority, > if two config file has same variable, old value(for system config) > must be overwrote by new value(for user config). But shouldn't it free the old value before overwriting? Thanks, Namhyung > > > > > > >>+ > >>+ return 0; > >>+}