diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c index b79c42c62557fea294e9156717024b5fd108159f..b6445d9e54533d224a89fbe98ad7fcfad52ac19d 100644 --- a/drivers/hwtracing/stm/core.c +++ b/drivers/hwtracing/stm/core.c @@ -781,17 +781,20 @@ static int stm_source_link_add(struct stm_source_device *src, static void __stm_source_link_drop(struct stm_source_device *src, struct stm_device *stm) { + struct stm_device *link; + spin_lock(&src->link_lock); - if (WARN_ON_ONCE(src->link != stm)) { + link = srcu_dereference_check(src->link, &stm_source_srcu, 1); + if (WARN_ON_ONCE(link != stm)) { spin_unlock(&src->link_lock); return; } - stm_output_free(src->link, &src->output); + stm_output_free(link, &src->output); /* caller must hold stm::link_lock */ list_del_init(&src->link_entry); /* matches stm_find_device() from stm_source_link_store() */ - stm_put_device(src->link); + stm_put_device(link); rcu_assign_pointer(src->link, NULL); spin_unlock(&src->link_lock); diff --git a/drivers/hwtracing/stm/stm.h b/drivers/hwtracing/stm/stm.h index cf33bf976abed90e46cdfecd6532e6fc078d53b2..95ece0292c991c8ad60f81c4a15fe4f3687d4504 100644 --- a/drivers/hwtracing/stm/stm.h +++ b/drivers/hwtracing/stm/stm.h @@ -74,7 +74,7 @@ struct stm_source_device { struct device dev; struct stm_source_data *data; spinlock_t link_lock; - struct stm_device *link; + struct stm_device __rcu *link; struct list_head link_entry; /* one output per stm_source device */ struct stp_policy_node *policy_node;