summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorArto Merilainen <amerilainen@nvidia.com>2014-05-28 09:00:43 +0300
committerWinnie Hsu <whsu@nvidia.com>2014-10-17 10:56:29 -0700
commit6876f819d21ef127f98999e3f21d83ecd402956b (patch)
tree5c9ecce93d2db6aa14a337e1120b6f08a12dc72f /drivers
parent83296fee29da1a2e6973157aa9f9d913071657bc (diff)
video: tegra: host: Fix debug dump
Currently the debug dump routine is vulnerable against tricky races. As normal operation is more important than getting the full dump always, this patch reworks mutex usage in debug dump routine: - lock the channel list is now before going through channels. This ensures that channel states remain valid even if some of the channels were finished during dump. - this patch modifies mutex_lock() calls to mutex_trylock() calls. This ensures that the function call cannot block. Bug 1517429 Change-Id: Idf170de196bcededbaec6c9031d268cf2d8bc35d (cherry picked from commit 544cbc483b973ca1c78173edcf2072434c02b5dd) Signed-off-by: Arto Merilainen <amerilainen@nvidia.com> Reviewed-on: http://git-master/r/498508 Reviewed-on: http://git-master/r/538724 GVS: Gerrit_Virtual_Submit Reviewed-by: Shreshtha Sahu <ssahu@nvidia.com> Tested-by: Shreshtha Sahu <ssahu@nvidia.com> Reviewed-by: Venkat Moganty <vmoganty@nvidia.com> Reviewed-by: Shridhar Rasal <srasal@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/tegra/host/debug.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/video/tegra/host/debug.c b/drivers/video/tegra/host/debug.c
index 900d30a84761..eb3394652808 100644
--- a/drivers/video/tegra/host/debug.c
+++ b/drivers/video/tegra/host/debug.c
@@ -56,7 +56,7 @@ static int show_channels(struct platform_device *pdev, void *data,
struct output *o = data;
struct nvhost_master *m;
struct nvhost_device_data *pdata;
- int index;
+ int index, locked;
if (pdev == NULL)
return 0;
@@ -64,6 +64,13 @@ static int show_channels(struct platform_device *pdev, void *data,
m = nvhost_get_host(pdev);
pdata = platform_get_drvdata(pdev);
+ /* acquire lock to prevent channel modifications */
+ locked = mutex_trylock(&m->chlist_mutex);
+ if (!locked) {
+ nvhost_debug_output(o, "unable to lock channel list\n");
+ return 0;
+ }
+
for (index = 0; index < pdata->num_channels; index++) {
ch = pdata->channels[index];
if (!ch || !ch->dev) {
@@ -71,19 +78,27 @@ static int show_channels(struct platform_device *pdev, void *data,
index + 1, pdev->name);
continue;
}
- nvhost_getchannel(ch);
- if (ch->chid != locked_id)
- mutex_lock(&ch->cdma.lock);
+
+ /* ensure that we get a lock */
+ locked = mutex_trylock(&ch->cdma.lock);
+ if (!(locked || ch->chid == locked_id)) {
+ nvhost_debug_output(o, "failed to lock channel %d cdma\n",
+ ch->chid);
+ continue;
+ }
+
if (fifo)
nvhost_get_chip_ops()->debug.show_channel_fifo(
m, ch, o, ch->chid);
nvhost_get_chip_ops()->debug.show_channel_cdma(
m, ch, o, ch->chid);
+
if (ch->chid != locked_id)
mutex_unlock(&ch->cdma.lock);
- nvhost_putchannel(ch);
}
+ mutex_unlock(&m->chlist_mutex);
+
return 0;
}