summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAurora pro automerger <aurora-pro-automerger@google.com>2022-08-30 17:43:48 +0000
committerJohn Scheible <johnscheible@google.com>2022-09-07 17:20:42 +0000
commit33208ffbc5e55846af03bcf708d7c91ed2934e4a (patch)
tree22da1d4a2504281ea7a7b3abcba8f9e3e3b08ac8
parent261baf5aa92fe1fb8a0a30d7e971117ed5b36de9 (diff)
downloadgs201-33208ffbc5e55846af03bcf708d7c91ed2934e4a.tar.gz
[Copybara Auto Merge]
gxp: Protect telemetry status in vd start/stop Bug: 234674375 GitOrigin-RevId: 5240c24d481643bb6836a6ee05c28d03d12dc152 Change-Id: I851bff5b6446ee684b2d9776a6f74bdbf99b2598
-rw-r--r--gxp-telemetry.c26
-rw-r--r--gxp-vd.c11
2 files changed, 30 insertions, 7 deletions
diff --git a/gxp-telemetry.c b/gxp-telemetry.c
index 93b301b..7eb18cb 100644
--- a/gxp-telemetry.c
+++ b/gxp-telemetry.c
@@ -390,6 +390,11 @@ int gxp_telemetry_enable(struct gxp_dev *gxp, u8 type)
uint core, virt_core;
struct gxp_virtual_device *vd;
+ /*
+ * `vd_semaphore` cannot be acquired while holding the telemetry lock,
+ * so acquire it here before locking the telemetry lock.
+ */
+ down_read(&gxp->vd_semaphore);
mutex_lock(&gxp->telemetry_mgr->lock);
switch (type) {
@@ -410,7 +415,6 @@ int gxp_telemetry_enable(struct gxp_dev *gxp, u8 type)
}
/* Map the buffers for any cores already running */
- down_read(&gxp->vd_semaphore);
for (core = 0; core < GXP_NUM_CORES; core++) {
vd = gxp->core_to_vd[core];
if (vd != NULL) {
@@ -438,7 +442,7 @@ int gxp_telemetry_enable(struct gxp_dev *gxp, u8 type)
refcount_inc(&data->ref_count);
data->is_enabled = true;
- goto up_sem;
+ goto out;
err:
while (core--) {
vd = gxp->core_to_vd[core];
@@ -450,10 +454,9 @@ err:
}
}
-up_sem:
- up_read(&gxp->vd_semaphore);
out:
mutex_unlock(&gxp->telemetry_mgr->lock);
+ up_read(&gxp->vd_semaphore);
return ret;
}
@@ -499,7 +502,14 @@ static int notify_core_and_wait_for_disable(struct gxp_dev *gxp, uint core,
msecs_to_jiffies(10));
retries_left--;
+ /*
+ * No function may attempt to acquire the `vd_semaphore` while
+ * holding the telemetry lock, so it must be released, then
+ * re-acquired once the `vd_semaphore` is held.
+ */
+ mutex_unlock(&gxp->telemetry_mgr->lock);
down_read(&gxp->vd_semaphore);
+ mutex_lock(&gxp->telemetry_mgr->lock);
}
/*
@@ -604,13 +614,17 @@ int gxp_telemetry_disable(struct gxp_dev *gxp, u8 type)
{
int ret;
- mutex_lock(&gxp->telemetry_mgr->lock);
+ /*
+ * `vd_semaphore` cannot be acquired while holding the telemetry lock,
+ * so acquire it here before locking the telemetry lock.
+ */
down_read(&gxp->vd_semaphore);
+ mutex_lock(&gxp->telemetry_mgr->lock);
ret = telemetry_disable_locked(gxp, type);
- up_read(&gxp->vd_semaphore);
mutex_unlock(&gxp->telemetry_mgr->lock);
+ up_read(&gxp->vd_semaphore);
return ret;
}
diff --git a/gxp-vd.c b/gxp-vd.c
index 70a4f18..ae07455 100644
--- a/gxp-vd.c
+++ b/gxp-vd.c
@@ -166,6 +166,8 @@ static int map_telemetry_buffers(struct gxp_dev *gxp,
int ret = 0;
struct buffer_data *buff_data;
+ mutex_lock(&gxp->telemetry_mgr->lock);
+
/* Map logging buffers if logging is enabled */
buff_data = gxp->telemetry_mgr->logging_buff_data;
if (buff_data && buff_data->is_enabled) {
@@ -174,7 +176,7 @@ static int map_telemetry_buffers(struct gxp_dev *gxp,
buff_data->size, buff_data->buffer_daddrs[core], 0);
/* Don't bother checking tracing if logging fails */
if (ret)
- return ret;
+ goto out;
}
/* Map tracing buffers if tracing is enabled */
@@ -194,6 +196,9 @@ static int map_telemetry_buffers(struct gxp_dev *gxp,
}
}
+out:
+ mutex_unlock(&gxp->telemetry_mgr->lock);
+
return ret;
}
@@ -203,6 +208,8 @@ static void unmap_telemetry_buffers(struct gxp_dev *gxp,
{
struct buffer_data *buff_data;
+ mutex_lock(&gxp->telemetry_mgr->lock);
+
buff_data = gxp->telemetry_mgr->logging_buff_data;
if (buff_data && buff_data->is_enabled)
gxp_dma_unmap_allocated_coherent_buffer(
@@ -214,6 +221,8 @@ static void unmap_telemetry_buffers(struct gxp_dev *gxp,
gxp_dma_unmap_allocated_coherent_buffer(
gxp, vd, BIT(virt_core), buff_data->size,
buff_data->buffer_daddrs[core]);
+
+ mutex_unlock(&gxp->telemetry_mgr->lock);
}
static int map_debug_dump_buffer(struct gxp_dev *gxp,