Message ID | 20210512211752.4103-3-mike.leach@linaro.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | coresight: syscfg: dynamic load, resource management | expand |
On Wed, May 12, 2021 at 10:17:46PM +0100, Mike Leach wrote: > CoreSight configurations and features can be added as kernel loadable > modules. This patch updates the load owner API to ensure that the module > cannot be unloaded either:- Please remove the '-'. It is not a big issue but you can be sure the various patch robots will complain. With that: Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org> > 1) if the config it supplies is in use > 2) if the module is not the last in the load order list. > > Signed-off-by: Mike Leach <mike.leach@linaro.org> > --- > .../hwtracing/coresight/coresight-syscfg.c | 39 ++++++++++++++++++- > .../hwtracing/coresight/coresight-syscfg.h | 1 + > 2 files changed, 39 insertions(+), 1 deletion(-) > > diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c > index ab5ec43a9dad..26c1a244c2b1 100644 > --- a/drivers/hwtracing/coresight/coresight-syscfg.c > +++ b/drivers/hwtracing/coresight/coresight-syscfg.c > @@ -368,6 +368,26 @@ int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc, > return err; > } > > +/* > + * Conditionally up reference count on owner to prevent unload. > + * > + * module loaded configs need to be locked in to prevent premature unload. > + */ > +static int cscfg_owner_get(struct cscfg_load_owner_info *owner_info) > +{ > + if ((owner_info->type == CSCFG_OWNER_MODULE) && > + (!try_module_get(owner_info->owner_handle))) > + return -EINVAL; > + return 0; > +} > + > +/* conditionally lower ref count on an owner */ > +static void cscfg_owner_put(struct cscfg_load_owner_info *owner_info) > +{ > + if (owner_info->type == CSCFG_OWNER_MODULE) > + module_put(owner_info->owner_handle); > +} > + > static void cscfg_remove_owned_csdev_configs(struct coresight_device *csdev, void *load_owner) > { > struct cscfg_config_csdev *config_csdev, *tmp; > @@ -497,6 +517,14 @@ int cscfg_load_config_sets(struct cscfg_config_desc **config_descs, > > /* add the load owner to the load order list */ > list_add_tail(&owner_info->item, &cscfg_mgr->load_order_list); > + if (!list_is_singular(&cscfg_mgr->load_order_list)) { > + /* lock previous item in load order list */ > + err = cscfg_owner_get(list_prev_entry(owner_info, item)); > + if (err) { > + cscfg_unload_owned_cfgs_feats(owner_info); > + list_del(&owner_info->item); > + } > + } > > exit_unlock: > mutex_unlock(&cscfg_mutex); > @@ -547,7 +575,11 @@ int cscfg_unload_config_sets(struct cscfg_load_owner_info *owner_info) > cscfg_unload_owned_cfgs_feats(owner_info); > > /* remove from load order list */ > - list_del(&load_list_item->item); > + if (!list_is_singular(&cscfg_mgr->load_order_list)) { > + /* unlock previous item in load order list */ > + cscfg_owner_put(list_prev_entry(owner_info, item)); > + } > + list_del(&owner_info->item); > > exit_unlock: > mutex_unlock(&cscfg_mutex); > @@ -737,6 +769,10 @@ int cscfg_activate_config(unsigned long cfg_hash) > > list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) { > if ((unsigned long)config_desc->event_ea->var == cfg_hash) { > + /* must ensure that config cannot be unloaded in use */ > + err = cscfg_owner_get(config_desc->load_owner); > + if (err) > + break; > /* > * increment the global active count - control changes to > * active configurations > @@ -777,6 +813,7 @@ void cscfg_deactivate_config(unsigned long cfg_hash) > if ((unsigned long)config_desc->event_ea->var == cfg_hash) { > atomic_dec(&config_desc->active_cnt); > atomic_dec(&cscfg_mgr->sys_active_cnt); > + cscfg_owner_put(config_desc->load_owner); > dev_dbg(cscfg_device(), "Deactivate config %s.\n", config_desc->name); > break; > } > diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h > index e2b2bdab31aa..1da37874f70f 100644 > --- a/drivers/hwtracing/coresight/coresight-syscfg.h > +++ b/drivers/hwtracing/coresight/coresight-syscfg.h > @@ -61,6 +61,7 @@ struct cscfg_registered_csdev { > /* owner types for loading and unloading of config and feature sets */ > enum cscfg_load_owner_type { > CSCFG_OWNER_PRELOAD, > + CSCFG_OWNER_MODULE, > }; > > /** > -- > 2.17.1 >
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index ab5ec43a9dad..26c1a244c2b1 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -368,6 +368,26 @@ int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc, return err; } +/* + * Conditionally up reference count on owner to prevent unload. + * + * module loaded configs need to be locked in to prevent premature unload. + */ +static int cscfg_owner_get(struct cscfg_load_owner_info *owner_info) +{ + if ((owner_info->type == CSCFG_OWNER_MODULE) && + (!try_module_get(owner_info->owner_handle))) + return -EINVAL; + return 0; +} + +/* conditionally lower ref count on an owner */ +static void cscfg_owner_put(struct cscfg_load_owner_info *owner_info) +{ + if (owner_info->type == CSCFG_OWNER_MODULE) + module_put(owner_info->owner_handle); +} + static void cscfg_remove_owned_csdev_configs(struct coresight_device *csdev, void *load_owner) { struct cscfg_config_csdev *config_csdev, *tmp; @@ -497,6 +517,14 @@ int cscfg_load_config_sets(struct cscfg_config_desc **config_descs, /* add the load owner to the load order list */ list_add_tail(&owner_info->item, &cscfg_mgr->load_order_list); + if (!list_is_singular(&cscfg_mgr->load_order_list)) { + /* lock previous item in load order list */ + err = cscfg_owner_get(list_prev_entry(owner_info, item)); + if (err) { + cscfg_unload_owned_cfgs_feats(owner_info); + list_del(&owner_info->item); + } + } exit_unlock: mutex_unlock(&cscfg_mutex); @@ -547,7 +575,11 @@ int cscfg_unload_config_sets(struct cscfg_load_owner_info *owner_info) cscfg_unload_owned_cfgs_feats(owner_info); /* remove from load order list */ - list_del(&load_list_item->item); + if (!list_is_singular(&cscfg_mgr->load_order_list)) { + /* unlock previous item in load order list */ + cscfg_owner_put(list_prev_entry(owner_info, item)); + } + list_del(&owner_info->item); exit_unlock: mutex_unlock(&cscfg_mutex); @@ -737,6 +769,10 @@ int cscfg_activate_config(unsigned long cfg_hash) list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) { if ((unsigned long)config_desc->event_ea->var == cfg_hash) { + /* must ensure that config cannot be unloaded in use */ + err = cscfg_owner_get(config_desc->load_owner); + if (err) + break; /* * increment the global active count - control changes to * active configurations @@ -777,6 +813,7 @@ void cscfg_deactivate_config(unsigned long cfg_hash) if ((unsigned long)config_desc->event_ea->var == cfg_hash) { atomic_dec(&config_desc->active_cnt); atomic_dec(&cscfg_mgr->sys_active_cnt); + cscfg_owner_put(config_desc->load_owner); dev_dbg(cscfg_device(), "Deactivate config %s.\n", config_desc->name); break; } diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h index e2b2bdab31aa..1da37874f70f 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.h +++ b/drivers/hwtracing/coresight/coresight-syscfg.h @@ -61,6 +61,7 @@ struct cscfg_registered_csdev { /* owner types for loading and unloading of config and feature sets */ enum cscfg_load_owner_type { CSCFG_OWNER_PRELOAD, + CSCFG_OWNER_MODULE, }; /**
CoreSight configurations and features can be added as kernel loadable modules. This patch updates the load owner API to ensure that the module cannot be unloaded either:- 1) if the config it supplies is in use 2) if the module is not the last in the load order list. Signed-off-by: Mike Leach <mike.leach@linaro.org> --- .../hwtracing/coresight/coresight-syscfg.c | 39 ++++++++++++++++++- .../hwtracing/coresight/coresight-syscfg.h | 1 + 2 files changed, 39 insertions(+), 1 deletion(-)