2019-03-29 14:12:17 +08:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
2019-03-22 14:52:12 +08:00
|
|
|
From: Pawel Furtak <pawel.furtak@intel.com>
|
|
|
|
Date: Mon, 4 Mar 2019 14:13:41 +0100
|
2019-03-29 14:12:17 +08:00
|
|
|
Subject: [PATCH] ASoC: Intel: Skl: Virt: Fix panic issue on HW pos update
|
2019-03-22 14:52:12 +08:00
|
|
|
|
|
|
|
snd_pcm_period_elapsed may result in substream close/open
|
|
|
|
thus list of open substreams should not be used to find
|
2019-03-23 08:48:44 +08:00
|
|
|
updated streams. This patch adds new list to manage
|
|
|
|
updated streams.
|
2019-03-22 14:52:12 +08:00
|
|
|
|
2019-03-23 08:48:44 +08:00
|
|
|
Change-Id: I6b83a95774840a8b6cae450086e41bed6ab77650
|
2019-03-22 14:52:12 +08:00
|
|
|
Tracked-On: OAM-76721
|
|
|
|
Signed-off-by: Pawel Furtak <pawel.furtak@intel.com>
|
2019-03-23 08:48:44 +08:00
|
|
|
Reviewed-by: Wojciech Jablonski <wojciech.jablonski@intel.com>
|
|
|
|
Tested-by: Wojciech Jablonski <wojciech.jablonski@intel.com>
|
2019-03-22 14:52:12 +08:00
|
|
|
---
|
|
|
|
.../soc/intel/skylake/virtio/skl-virtio-fe.c | 62 ++++++++++++++-----
|
|
|
|
.../soc/intel/skylake/virtio/skl-virtio-fe.h | 8 +++
|
|
|
|
2 files changed, 56 insertions(+), 14 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/sound/soc/intel/skylake/virtio/skl-virtio-fe.c b/sound/soc/intel/skylake/virtio/skl-virtio-fe.c
|
2019-03-29 14:12:17 +08:00
|
|
|
index d627eaf..1085d75 100644
|
2019-03-22 14:52:12 +08:00
|
|
|
--- a/sound/soc/intel/skylake/virtio/skl-virtio-fe.c
|
|
|
|
+++ b/sound/soc/intel/skylake/virtio/skl-virtio-fe.c
|
2019-03-23 08:48:44 +08:00
|
|
|
@@ -324,8 +324,42 @@ static void vfe_cmd_tx_done(struct virtqueue *vq)
|
2019-03-22 14:52:12 +08:00
|
|
|
static void vfe_cmd_handle_rx(struct virtqueue *vq)
|
|
|
|
{
|
|
|
|
struct snd_skl_vfe *vfe;
|
|
|
|
+ unsigned long irq_flags;
|
|
|
|
+ struct vfe_substream_info *substr_info, *tmp;
|
|
|
|
+ struct vfe_updated_substream *updated_stream;
|
|
|
|
+ struct vfe_stream_pos_desc *pos_desc;
|
|
|
|
|
|
|
|
vfe = vq->vdev->priv;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ spin_lock_irqsave(&vfe->substream_info_lock, irq_flags);
|
|
|
|
+ list_for_each_entry_safe(substr_info, tmp,
|
|
|
|
+ &vfe->substr_info_list, list) {
|
|
|
|
+ pos_desc = substr_info->pos_desc;
|
|
|
|
+ if (!pos_desc ||
|
|
|
|
+ pos_desc->be_irq_cnt == pos_desc->fe_irq_cnt)
|
|
|
|
+ continue;
|
|
|
|
+ if (pos_desc->be_irq_cnt - pos_desc->fe_irq_cnt > 1)
|
|
|
|
+ dev_warn(&vfe->vdev->dev, "Missed interrupts on fe side\n");
|
|
|
|
+ pos_desc->fe_irq_cnt = pos_desc->be_irq_cnt;
|
|
|
|
+
|
|
|
|
+ updated_stream =
|
|
|
|
+ kzalloc(sizeof(*updated_stream), GFP_ATOMIC);
|
|
|
|
+
|
2019-03-23 08:48:44 +08:00
|
|
|
+ if (!updated_stream) {
|
|
|
|
+ dev_err(&vfe->vdev->dev,
|
|
|
|
+ "Failed to allocate stream update descriptor\n");
|
|
|
|
+ goto release_lock;
|
|
|
|
+ }
|
2019-03-22 14:52:12 +08:00
|
|
|
+
|
|
|
|
+ updated_stream->substream = substr_info->substream;
|
|
|
|
+ spin_lock(&vfe->updated_streams_lock);
|
|
|
|
+ list_add_tail(&updated_stream->list, &vfe->updated_streams);
|
|
|
|
+ spin_unlock(&vfe->updated_streams_lock);
|
|
|
|
+ }
|
2019-03-23 08:48:44 +08:00
|
|
|
+release_lock:
|
2019-03-22 14:52:12 +08:00
|
|
|
+ spin_unlock_irqrestore(&vfe->substream_info_lock, irq_flags);
|
|
|
|
+
|
|
|
|
queue_work(vfe->posn_update_queue,
|
|
|
|
&vfe->posn_update_work);
|
|
|
|
}
|
2019-03-23 08:48:44 +08:00
|
|
|
@@ -402,24 +436,20 @@ static void vfe_not_handle_rx(struct virtqueue *vq)
|
2019-03-22 14:52:12 +08:00
|
|
|
|
|
|
|
static void vfe_handle_posn(struct work_struct *work)
|
|
|
|
{
|
|
|
|
- struct vfe_substream_info *substr_info;
|
|
|
|
- struct vfe_stream_pos_desc *pos_desc;
|
|
|
|
+ struct vfe_updated_substream *updated_stream_desc;
|
|
|
|
+ unsigned long irq_flags;
|
|
|
|
struct snd_skl_vfe *vfe =
|
|
|
|
container_of(work, struct snd_skl_vfe, posn_update_work);
|
|
|
|
|
|
|
|
- /*stnc pos_desc*/
|
|
|
|
- rmb();
|
2019-03-23 08:48:44 +08:00
|
|
|
-
|
2019-03-22 14:52:12 +08:00
|
|
|
- list_for_each_entry(substr_info, &vfe->substr_info_list, list) {
|
|
|
|
- pos_desc = substr_info->pos_desc;
|
|
|
|
- if (!pos_desc ||
|
|
|
|
- pos_desc->be_irq_cnt == pos_desc->fe_irq_cnt)
|
|
|
|
- continue;
|
|
|
|
- if (pos_desc->be_irq_cnt - pos_desc->fe_irq_cnt > 1)
|
|
|
|
- dev_warn(&vfe->vdev->dev, "Missed interrupts on fe side\n");
|
2019-03-23 08:48:44 +08:00
|
|
|
+ while (!list_empty(&vfe->updated_streams)) {
|
2019-03-22 14:52:12 +08:00
|
|
|
+ spin_lock_irqsave(&vfe->updated_streams_lock, irq_flags);
|
|
|
|
+ updated_stream_desc = list_first_entry(&vfe->updated_streams,
|
|
|
|
+ struct vfe_updated_substream, list);
|
|
|
|
+ list_del(&updated_stream_desc->list);
|
|
|
|
+ spin_unlock_irqrestore(&vfe->updated_streams_lock, irq_flags);
|
|
|
|
|
|
|
|
- snd_pcm_period_elapsed(substr_info->substream);
|
|
|
|
- pos_desc->fe_irq_cnt = pos_desc->be_irq_cnt;
|
|
|
|
+ snd_pcm_period_elapsed(updated_stream_desc->substream);
|
|
|
|
+ kfree(updated_stream_desc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-23 08:48:44 +08:00
|
|
|
@@ -570,6 +600,8 @@ int vfe_pcm_close(struct snd_pcm_substream *substream)
|
2019-03-22 14:52:12 +08:00
|
|
|
sstream_info = vfe_find_substream_info(vfe, substream);
|
|
|
|
|
|
|
|
if (sstream_info) {
|
|
|
|
+ kfree(sstream_info->pos_desc);
|
|
|
|
+
|
|
|
|
list_del(&sstream_info->list);
|
|
|
|
kfree(sstream_info);
|
|
|
|
}
|
2019-03-23 08:48:44 +08:00
|
|
|
@@ -1116,6 +1148,8 @@ static int vfe_init(struct virtio_device *vdev)
|
2019-03-22 14:52:12 +08:00
|
|
|
INIT_LIST_HEAD(&vfe->substr_info_list);
|
|
|
|
spin_lock_init(&vfe->ipc_vq_lock);
|
|
|
|
INIT_LIST_HEAD(&vfe->expired_msg_list);
|
|
|
|
+ spin_lock_init(&vfe->updated_streams_lock);
|
|
|
|
+ INIT_LIST_HEAD(&vfe->updated_streams);
|
|
|
|
|
|
|
|
INIT_WORK(&vfe->posn_update_work, vfe_handle_posn);
|
|
|
|
INIT_WORK(&vfe->msg_timeout_work, vfe_not_tx_timeout_handler);
|
|
|
|
diff --git a/sound/soc/intel/skylake/virtio/skl-virtio-fe.h b/sound/soc/intel/skylake/virtio/skl-virtio-fe.h
|
2019-03-29 14:12:17 +08:00
|
|
|
index 74e7acb..fcc2dc2 100644
|
2019-03-22 14:52:12 +08:00
|
|
|
--- a/sound/soc/intel/skylake/virtio/skl-virtio-fe.h
|
|
|
|
+++ b/sound/soc/intel/skylake/virtio/skl-virtio-fe.h
|
|
|
|
@@ -25,6 +25,11 @@ struct vfe_substream_info {
|
|
|
|
struct list_head list;
|
|
|
|
};
|
|
|
|
|
|
|
|
+struct vfe_updated_substream {
|
|
|
|
+ struct snd_pcm_substream *substream;
|
|
|
|
+ struct list_head list;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
struct vskl_vfe_tplg {
|
|
|
|
struct firmware tplg_data;
|
|
|
|
u64 data_ready;
|
|
|
|
@@ -69,6 +74,9 @@ struct snd_skl_vfe {
|
|
|
|
|
|
|
|
struct list_head expired_msg_list;
|
|
|
|
|
|
|
|
+ spinlock_t updated_streams_lock;
|
|
|
|
+ struct list_head updated_streams;
|
|
|
|
+
|
|
|
|
int (*send_dsp_ipc_msg)(struct snd_skl_vfe *vfe,
|
|
|
|
struct ipc_message *msg);
|
|
|
|
int (*notify_machine_probe)(struct snd_skl_vfe *vfe,
|
|
|
|
--
|
2019-03-29 14:12:17 +08:00
|
|
|
2.21.0
|
2019-03-22 14:52:12 +08:00
|
|
|
|