voice-proto: long command timeout only for voice blob sends
The blanket 240 s audioreach_send_cmd_sync timeout (cfc2b6a276) broke
boot audio: apm_probe's GET_SPF_STATE ready poll gets no answer when
sent before the DSP audio framework is up (the command is simply lost),
so probe held the shared command mutex for the full 240 s. That stalls
snd_q6apm's module init past udev's worker timeout, q6prm never gets
loaded, the LPI pinctrl never finds its 'core' clock and the sound card
never assembles (every boot since 2026-07-10 had no card). It also
queued every later voice-proto command behind the mutex for minutes,
which sessions 8-11 misread as slow DSP responses.
Restore the mainline 30 s default via audioreach_send_cmd_sync_timeout
and pass 240 s only from the voice-proto blob paths (a cold TX
GRAPH_OPEN through the Fluence FastRPC loads takes >120 s).
Assisted-by: Claude:claude-fable-5
This commit is contained in:
parent
2d3c1ed4cf
commit
806ec77a1f
5 changed files with 42 additions and 6 deletions
|
|
@ -576,10 +576,11 @@ void *audioreach_alloc_graph_pkt(struct q6apm *apm,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(audioreach_alloc_graph_pkt);
|
||||
|
||||
int audioreach_send_cmd_sync(struct device *dev, gpr_device_t *gdev,
|
||||
int audioreach_send_cmd_sync_timeout(struct device *dev, gpr_device_t *gdev,
|
||||
struct gpr_ibasic_rsp_result_t *result, struct mutex *cmd_lock,
|
||||
gpr_port_t *port, wait_queue_head_t *cmd_wait,
|
||||
const struct gpr_pkt *pkt, uint32_t rsp_opcode)
|
||||
const struct gpr_pkt *pkt, uint32_t rsp_opcode,
|
||||
unsigned long timeout_s)
|
||||
{
|
||||
|
||||
const struct gpr_hdr *hdr = &pkt->hdr;
|
||||
|
|
@ -601,9 +602,9 @@ int audioreach_send_cmd_sync(struct device *dev, gpr_device_t *gdev,
|
|||
|
||||
if (rsp_opcode)
|
||||
rc = wait_event_timeout(*cmd_wait, (result->opcode == hdr->opcode) ||
|
||||
(result->opcode == rsp_opcode), 240 * HZ);
|
||||
(result->opcode == rsp_opcode), timeout_s * HZ);
|
||||
else
|
||||
rc = wait_event_timeout(*cmd_wait, (result->opcode == hdr->opcode), 240 * HZ);
|
||||
rc = wait_event_timeout(*cmd_wait, (result->opcode == hdr->opcode), timeout_s * HZ);
|
||||
|
||||
if (!rc) {
|
||||
dev_err(dev, "CMD timeout for [%x] opcode\n", hdr->opcode);
|
||||
|
|
@ -620,6 +621,16 @@ err:
|
|||
mutex_unlock(cmd_lock);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(audioreach_send_cmd_sync_timeout);
|
||||
|
||||
int audioreach_send_cmd_sync(struct device *dev, gpr_device_t *gdev,
|
||||
struct gpr_ibasic_rsp_result_t *result, struct mutex *cmd_lock,
|
||||
gpr_port_t *port, wait_queue_head_t *cmd_wait,
|
||||
const struct gpr_pkt *pkt, uint32_t rsp_opcode)
|
||||
{
|
||||
return audioreach_send_cmd_sync_timeout(dev, gdev, result, cmd_lock,
|
||||
port, cmd_wait, pkt, rsp_opcode, 30);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(audioreach_send_cmd_sync);
|
||||
|
||||
int audioreach_graph_send_cmd_sync(struct q6apm_graph *graph, const struct gpr_pkt *pkt,
|
||||
|
|
|
|||
|
|
@ -845,6 +845,11 @@ void audioreach_graph_free_buf(struct q6apm_graph *graph);
|
|||
int audioreach_send_cmd_sync(struct device *dev, gpr_device_t *gdev, struct gpr_ibasic_rsp_result_t *result,
|
||||
struct mutex *cmd_lock, gpr_port_t *port, wait_queue_head_t *cmd_wait,
|
||||
const struct gpr_pkt *pkt, uint32_t rsp_opcode);
|
||||
int audioreach_send_cmd_sync_timeout(struct device *dev, gpr_device_t *gdev,
|
||||
struct gpr_ibasic_rsp_result_t *result,
|
||||
struct mutex *cmd_lock, gpr_port_t *port, wait_queue_head_t *cmd_wait,
|
||||
const struct gpr_pkt *pkt, uint32_t rsp_opcode,
|
||||
unsigned long timeout_s);
|
||||
int audioreach_graph_send_cmd_sync(struct q6apm_graph *graph, const struct gpr_pkt *pkt,
|
||||
uint32_t rsp_opcode);
|
||||
int audioreach_set_media_format(struct q6apm_graph *graph,
|
||||
|
|
|
|||
|
|
@ -107,7 +107,15 @@ static int q6vp_send(uint32_t opcode, const void *payload, uint32_t size)
|
|||
|
||||
memcpy((void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE, payload, size);
|
||||
|
||||
ret = q6apm_send_cmd_sync(q6vp_apm, pkt, rsp_opcode);
|
||||
/*
|
||||
* Voice blobs need the long wait: a cold TX GRAPH_OPEN that has to
|
||||
* FastRPC-load the Fluence pp modules takes >120 s. Regular audio
|
||||
* commands (and especially the probe-time GET_SPF_STATE ready poll)
|
||||
* must keep the short default or they hold the shared command mutex
|
||||
* hostage at boot: a 240 s stall in apm_probe delays module loading
|
||||
* past udev's worker timeout and the sound card never assembles.
|
||||
*/
|
||||
ret = q6apm_send_cmd_sync_timeout(q6vp_apm, pkt, rsp_opcode, 240);
|
||||
kfree(pkt);
|
||||
|
||||
return ret;
|
||||
|
|
@ -234,7 +242,7 @@ static int q6vp_send_oob(uint32_t opcode, const void *payload, uint32_t size)
|
|||
cmd_header->mem_map_handle = q6vp_info->mem_map_handle;
|
||||
cmd_header->payload_size = size;
|
||||
|
||||
ret = q6apm_send_cmd_sync(q6vp_apm, pkt, 0);
|
||||
ret = q6apm_send_cmd_sync_timeout(q6vp_apm, pkt, 0, 240);
|
||||
kfree(pkt);
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,16 @@ int q6apm_send_cmd_sync(struct q6apm *apm, const struct gpr_pkt *pkt,
|
|||
NULL, &apm->wait, pkt, rsp_opcode);
|
||||
}
|
||||
|
||||
int q6apm_send_cmd_sync_timeout(struct q6apm *apm, const struct gpr_pkt *pkt,
|
||||
uint32_t rsp_opcode, unsigned long timeout_s)
|
||||
{
|
||||
gpr_device_t *gdev = apm->gdev;
|
||||
|
||||
return audioreach_send_cmd_sync_timeout(&gdev->dev, gdev, &apm->result,
|
||||
&apm->lock, NULL, &apm->wait,
|
||||
pkt, rsp_opcode, timeout_s);
|
||||
}
|
||||
|
||||
static struct audioreach_graph *q6apm_get_audioreach_graph(struct q6apm *apm, uint32_t graph_id)
|
||||
{
|
||||
struct audioreach_graph_info *info;
|
||||
|
|
|
|||
|
|
@ -144,6 +144,8 @@ int q6apm_unmap_memory_fixed_region(struct device *dev, unsigned int graph_id);
|
|||
/* Helpers */
|
||||
int q6apm_send_cmd_sync(struct q6apm *apm, const struct gpr_pkt *pkt,
|
||||
uint32_t rsp_opcode);
|
||||
int q6apm_send_cmd_sync_timeout(struct q6apm *apm, const struct gpr_pkt *pkt,
|
||||
uint32_t rsp_opcode, unsigned long timeout_s);
|
||||
|
||||
/* Callback for graph specific */
|
||||
struct audioreach_module *q6apm_find_module_by_mid(struct q6apm_graph *graph,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue