ASoC: rsnd: ssi: fix race condition in rsnd_ssi_pointer_update
Currently there is race condition between set of byte_pos and wrap it around when new buffer starts. If .pointer is called in-between it will result in inconsistent pointer position be returned from .pointer callback. This patch increments buffer pointer atomically to avoid this issue. Signed-off-by: Jiada Wang <jiada_wang@mentor.com> Reviewed-by: Takashi Sakamoto <takashi.sakamoto@miraclelinux.com> Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
a91d7fb970
commit
33f801366b
|
@ -446,25 +446,29 @@ static bool rsnd_ssi_pointer_update(struct rsnd_mod *mod,
|
|||
int byte)
|
||||
{
|
||||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||
bool ret = false;
|
||||
int byte_pos;
|
||||
|
||||
ssi->byte_pos += byte;
|
||||
byte_pos = ssi->byte_pos + byte;
|
||||
|
||||
if (ssi->byte_pos >= ssi->next_period_byte) {
|
||||
if (byte_pos >= ssi->next_period_byte) {
|
||||
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
||||
|
||||
ssi->period_pos++;
|
||||
ssi->next_period_byte += ssi->byte_per_period;
|
||||
|
||||
if (ssi->period_pos >= runtime->periods) {
|
||||
ssi->byte_pos = 0;
|
||||
byte_pos = 0;
|
||||
ssi->period_pos = 0;
|
||||
ssi->next_period_byte = ssi->byte_per_period;
|
||||
}
|
||||
|
||||
return true;
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
WRITE_ONCE(ssi->byte_pos, byte_pos);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -838,7 +842,7 @@ static int rsnd_ssi_pointer(struct rsnd_mod *mod,
|
|||
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
|
||||
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
|
||||
|
||||
*pointer = bytes_to_frames(runtime, ssi->byte_pos);
|
||||
*pointer = bytes_to_frames(runtime, READ_ONCE(ssi->byte_pos));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue