neuron: ch_haven: Move msgq init to sync thread

The neuron channels may init and probe before the secondary vm is
loaded and the resources queried from resource manager. This results
in either a blocking call or EAGAIN returned when sending a doorbell.

Move the msgq_init call from the probe to the channel sync thread. This
will ensure the init thread can continue if the doorbell send api needs
to block or busywait loop.

Change-Id: I0f5562968d59a3dc0a361aca9e4e60ffebcb70be
Signed-off-by: Chris Lew <clew@codeaurora.org>
This commit is contained in:
Chris Lew 2020-04-24 12:33:28 -07:00 • committed by Elliot Berman
commit 90f8f682ed
2 changed files with 19 additions and 21 deletions

View file

@ -251,6 +251,11 @@ static int channel_sync_thread(void *data)
struct neuron_shmem_channel_header *hdr;
struct neuron_mq_data_priv *priv = (struct neuron_mq_data_priv *)data;
/* Init the shared memory header and local message queue. */
if (msgq_init(priv)) {
pr_err("%s: msgq_init failed\n", __func__);
return 0;
}
hdr = (struct neuron_shmem_channel_header *)priv->base;
/* Waiting for head being updated by the sender. */
@ -380,12 +385,7 @@ static int channel_hh_probe(struct neuron_channel *cdev)
goto fail_rx_dbl;
}
/* Init the shared memory header and local message queue. */
ret = msgq_init(priv);
if (ret)
goto fail_mask;
init_waitqueue_head(&priv->wait_q);
/* Start the thread for syncing with the sender. */
priv->sync_thread = kthread_run(channel_sync_thread, priv,
"recv_sync_thread");
@ -394,8 +394,6 @@ static int channel_hh_probe(struct neuron_channel *cdev)
return 0;
fail_mask:
hh_dbl_rx_unregister(priv->rx_dbl);
fail_rx_dbl:
hh_dbl_tx_unregister(priv->tx_dbl);
fail_tx_dbl:

View file

@ -217,6 +217,19 @@ static int read_config(struct neuron_mq_data_priv *priv)
return 0;
}
static void msgq_init(struct neuron_mq_data_priv *priv)
{
struct neuron_shmem_channel_header *hdr = priv->base;
struct neuron_msg_queue *msgq = &priv->msgq;
msgq->headp = &hdr->head;
msgq->space_for_next_p = &hdr->space_for_next;
msgq->offset = (u32)-1;
/* Set it to -1 as UNINITIALIZED */
smp_store_release(msgq->headp, (u32)-1);
}
/* Thread to sync with the receiver. Note: this thread might never finishes if
* it fails to sync with the peer.
*/
@ -225,6 +238,7 @@ static int channel_sync_thread(void *data)
struct neuron_mq_data_priv *priv = (struct neuron_mq_data_priv *)data;
struct neuron_shmem_channel_header *hdr;
msgq_init(priv);
hdr = (struct neuron_shmem_channel_header *)priv->base;
hdr->version = CHANNEL_VERSION;
hdr->tail_offset = -1;
@ -265,19 +279,6 @@ static int channel_sync_thread(void *data)
return 0;
}
static void msgq_init(struct neuron_mq_data_priv *priv)
{
struct neuron_shmem_channel_header *hdr = priv->base;
struct neuron_msg_queue *msgq = &priv->msgq;
msgq->headp = &hdr->head;
msgq->space_for_next_p = &hdr->space_for_next;
msgq->offset = (u32)-1;
/* Set it to -1 as UNINITIALIZED */
smp_store_release(msgq->headp, (u32)-1);
}
static int channel_hh_map_memory(struct neuron_mq_data_priv *priv,
struct device *dev)
{
@ -367,7 +368,6 @@ static int channel_hh_probe(struct neuron_channel *cdev)
goto fail_rx_dbl;
}
msgq_init(priv);
init_waitqueue_head(&priv->wait_q);
/* Start the thread for syncing with the receiver. */
priv->sync_thread = kthread_run(channel_sync_thread, priv,