From c7d62ab5570aef401c40bd3c51cff6a71e21f907 Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Fri, 1 Apr 2022 18:07:21 +0800 Subject: [PATCH] coresight-stm: fix list_add double add issue In race condition, when stm_source_link_add is called, the link from stm_source to stm device has been established, src->Link_entry has been added to STM->link_list, this is the root cause for this isse. this change add a mutex lock to ensure that only one thread can enter stm_source_link_store(). Change-Id: I8abf4275c590508f316a1337e604a4ed58563626 Signed-off-by: Yuanfang Zhang --- drivers/hwtracing/stm/core.c | 9 ++++++--- drivers/hwtracing/stm/stm.h | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c index 2712e699ba08..b235ab4f3b4f 100644 --- a/drivers/hwtracing/stm/core.c +++ b/drivers/hwtracing/stm/core.c @@ -1171,12 +1171,14 @@ static ssize_t stm_source_link_store(struct device *dev, struct stm_device *link; int err; + mutex_lock(&src->link_mutex); stm_source_link_drop(src); link = stm_find_device(buf); - if (!link) + if (!link) { + mutex_unlock(&src->link_mutex); return -EINVAL; - + } pm_runtime_get(&link->dev); err = stm_source_link_add(src, link); @@ -1185,7 +1187,7 @@ static ssize_t stm_source_link_store(struct device *dev, /* matches the stm_find_device() above */ stm_put_device(link); } - + mutex_unlock(&src->link_mutex); return err ? : count; } @@ -1251,6 +1253,7 @@ int stm_source_register_device(struct device *parent, stm_output_init(&src->output); spin_lock_init(&src->link_lock); + mutex_init(&src->link_mutex); INIT_LIST_HEAD(&src->link_entry); src->data = data; data->src = src; diff --git a/drivers/hwtracing/stm/stm.h b/drivers/hwtracing/stm/stm.h index a9be49fc7a6b..8d5d5b58c737 100644 --- a/drivers/hwtracing/stm/stm.h +++ b/drivers/hwtracing/stm/stm.h @@ -79,6 +79,7 @@ void stm_put_device(struct stm_device *stm); struct stm_source_device { struct device dev; struct stm_source_data *data; + struct mutex link_mutex; spinlock_t link_lock; struct stm_device __rcu *link; struct list_head link_entry;