Skip to content

Commit 09c5cf1

Browse files
coresight: tmc: getting rid of multiple read access
Allowing multiple readers to access the trace data simultaniously via sysFS provides no shortage of opportunity for race condition, mandates two variable to be maintained (drvdata::read_count and drvdata::reading), makes the code complex and provide little advantages, if any. This patch streamlines the read process by restricting trace data access to a single user. That way drvdata::read_count can be eliminated and race conditions (along with faulty error handling) in function tmc_open() and tmc_release() eliminated. Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> (cherry picked from commit f74debbea0885ebb65fb3fa4e598323f40b03f5f)
1 parent 17c61c3 commit 09c5cf1

4 files changed

Lines changed: 18 additions & 17 deletions

File tree

drivers/hwtracing/coresight/coresight-tmc-etf.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,11 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata)
260260

261261
spin_lock_irqsave(&drvdata->spinlock, flags);
262262

263+
if (drvdata->reading) {
264+
ret = -EBUSY;
265+
goto out;
266+
}
267+
263268
/* There is no point in reading a TMC in HW FIFO mode */
264269
mode = readl_relaxed(drvdata->base + TMC_MODE);
265270
if (mode != TMC_MODE_CIRCULAR_BUFFER) {

drivers/hwtracing/coresight/coresight-tmc-etr.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,10 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
188188
return -EINVAL;
189189

190190
spin_lock_irqsave(&drvdata->spinlock, flags);
191+
if (drvdata->reading) {
192+
ret = -EBUSY;
193+
goto out;
194+
}
191195

192196
/* If drvdata::buf is NULL the trace data has been read already */
193197
if (drvdata->buf == NULL) {

drivers/hwtracing/coresight/coresight-tmc.c

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ static int tmc_read_prepare(struct tmc_drvdata *drvdata)
9595
return ret;
9696
}
9797

98-
static void tmc_read_unprepare(struct tmc_drvdata *drvdata)
98+
static int tmc_read_unprepare(struct tmc_drvdata *drvdata)
9999
{
100100
int ret = 0;
101101

@@ -113,21 +113,20 @@ static void tmc_read_unprepare(struct tmc_drvdata *drvdata)
113113

114114
if (!ret)
115115
dev_info(drvdata->dev, "TMC read end\n");
116+
117+
return ret;
116118
}
117119

118120
static int tmc_open(struct inode *inode, struct file *file)
119121
{
122+
int ret;
120123
struct tmc_drvdata *drvdata = container_of(file->private_data,
121124
struct tmc_drvdata, miscdev);
122-
int ret = 0;
123-
124-
if (drvdata->read_count++)
125-
goto out;
126125

127126
ret = tmc_read_prepare(drvdata);
128127
if (ret)
129128
return ret;
130-
out:
129+
131130
nonseekable_open(inode, file);
132131

133132
dev_dbg(drvdata->dev, "%s: successfully opened\n", __func__);
@@ -167,19 +166,14 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
167166

168167
static int tmc_release(struct inode *inode, struct file *file)
169168
{
169+
int ret;
170170
struct tmc_drvdata *drvdata = container_of(file->private_data,
171171
struct tmc_drvdata, miscdev);
172172

173-
if (--drvdata->read_count) {
174-
if (drvdata->read_count < 0) {
175-
dev_err(drvdata->dev, "mismatched close\n");
176-
drvdata->read_count = 0;
177-
}
178-
goto out;
179-
}
173+
ret = tmc_read_unprepare(drvdata);
174+
if (ret)
175+
return ret;
180176

181-
tmc_read_unprepare(drvdata);
182-
out:
183177
dev_dbg(drvdata->dev, "%s: released\n", __func__);
184178
return 0;
185179
}

drivers/hwtracing/coresight/coresight-tmc.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ enum tmc_mem_intf_width {
9494
* @csdev: component vitals needed by the framework.
9595
* @miscdev: specifics to handle "/dev/xyz.tmc" entry.
9696
* @spinlock: only one at a time pls.
97-
* @read_count: manages preparation of buffer for reading.
9897
* @buf: area of memory where trace data get sent.
9998
* @paddr: DMA start location in RAM.
10099
* @vaddr: virtual representation of @paddr.
@@ -109,7 +108,6 @@ struct tmc_drvdata {
109108
struct coresight_device *csdev;
110109
struct miscdevice miscdev;
111110
spinlock_t spinlock;
112-
int read_count;
113111
bool reading;
114112
char *buf;
115113
dma_addr_t paddr;

0 commit comments

Comments
 (0)