Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0efc646a authored by Mathieu Poirier's avatar Mathieu Poirier Committed by Yabin Cui
Browse files

UPSTREAM: coresight: Properly address concurrency in sink::update() functions



(Upstream commit 0916447c8728ed1ffa2bf9feee220f01d802b37e).

When operating in CPU-wide trace scenarios and working with an N:1
source/sink HW topology, update() functions need to be made atomic
in order to avoid racing with start and stop operations.

Signed-off-by: default avatarMathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Tested-by: default avatarLeo Yan <leo.yan@linaro.org>
Tested-by: default avatarRobert Walker <robert.walker@arm.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>

Bug: 140266694
Change-Id: If16c146cc4721acc005c7db3d88e57d38fe48ece
Signed-off-by: default avatarYabin Cui <yabinc@google.com>
parent 14b94671
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -413,7 +413,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev,
	const u32 *barrier;
	const u32 *barrier;
	u32 read_ptr, write_ptr, capacity;
	u32 read_ptr, write_ptr, capacity;
	u32 status, read_data;
	u32 status, read_data;
	unsigned long offset, to_read;
	unsigned long offset, to_read, flags;
	struct cs_buffers *buf = sink_config;
	struct cs_buffers *buf = sink_config;
	struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
	struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);


@@ -422,6 +422,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev,


	capacity = drvdata->buffer_depth * ETB_FRAME_SIZE_WORDS;
	capacity = drvdata->buffer_depth * ETB_FRAME_SIZE_WORDS;


	spin_lock_irqsave(&drvdata->spinlock, flags);
	__etb_disable_hw(drvdata);
	__etb_disable_hw(drvdata);
	CS_UNLOCK(drvdata->base);
	CS_UNLOCK(drvdata->base);


@@ -532,6 +533,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev,
	}
	}
	__etb_enable_hw(drvdata);
	__etb_enable_hw(drvdata);
	CS_LOCK(drvdata->base);
	CS_LOCK(drvdata->base);
	spin_unlock_irqrestore(&drvdata->spinlock, flags);


	return to_read;
	return to_read;
}
}
+3 −1
Original line number Original line Diff line number Diff line
@@ -416,7 +416,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
	u32 *buf_ptr;
	u32 *buf_ptr;
	u64 read_ptr, write_ptr;
	u64 read_ptr, write_ptr;
	u32 status;
	u32 status;
	unsigned long offset, to_read;
	unsigned long offset, to_read, flags;
	struct cs_buffers *buf = sink_config;
	struct cs_buffers *buf = sink_config;
	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);


@@ -427,6 +427,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
	if (WARN_ON_ONCE(drvdata->mode != CS_MODE_PERF))
	if (WARN_ON_ONCE(drvdata->mode != CS_MODE_PERF))
		return 0;
		return 0;


	spin_lock_irqsave(&drvdata->spinlock, flags);
	CS_UNLOCK(drvdata->base);
	CS_UNLOCK(drvdata->base);


	tmc_flush_and_stop(drvdata);
	tmc_flush_and_stop(drvdata);
@@ -520,6 +521,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
		to_read = buf->nr_pages << PAGE_SHIFT;
		to_read = buf->nr_pages << PAGE_SHIFT;
	}
	}
	CS_LOCK(drvdata->base);
	CS_LOCK(drvdata->base);
	spin_unlock_irqrestore(&drvdata->spinlock, flags);


	return to_read;
	return to_read;
}
}