[alsa-devel] [alsa-lib][v1.1.19][pcm][multi plug] multi plug stuck in busy loop which caused high cpu loading.

eleven xiang eleven.xiang at gmail.com
Mon Jul 29 09:32:39 CEST 2019


Dear Jaroslav,

So glad to read your mail ~

I have read the multi plug pcm's
*snd_pcm_multi_may_wait_for_avail_min*() function,
from your reply, this function will wait for avail_min ready ?

and from the detail implementation, multi pcm's
*snd_pcm_multi_may_wait_for_avail_min*()  will call each pcm's
*may_wait_for_avail_min* function.
And here is the problem, the hardware pcm_hw device didn't implement this
interface, so it will not wait, just skip it.

as for why snd_pcm_wait() does not wait even when avil==0, we found below
code:

*// snd_pcm_wait() only poll master slave fd.*
static int snd_pcm_multi_poll_descriptors_count(snd_pcm_t *pcm)
{
    snd_pcm_multi_t *multi = pcm->private_data;
    snd_pcm_t **slave_0* = multi->slaves[multi->master_slave].pcm;
    return snd_pcm_poll_descriptors_count(*slave_0*);  *// only check
master slave pcm ??*
}

back to our issue, the master slave was ready to read, but the second slave
pcm wasn' t ready,
so snd_pcm_wait() will return immediately due to master slave ready.

Thanks

Jaroslav Kysela <perex at perex.cz> 于2019年7月27日周六 下午5:38写道:

> Dne 25. 07. 19 v 11:59 eleven xiang napsal(a):
> > Dear,
> >
> > Currently, for Audio Echo Cancellation process, we combined both mic
> signal
> > and reference signal into one pcm with the multi plug.
> > And both the mic and ref signal are hw pcm devices, and they lived in the
> > same sound card in driver.
> >
> > Here is the issue:
> >
> > 1. the master slave pcm device is already for read;
> > 2. the second salve pcm is not ready for read, which means no data;
> > 3. under this situation, snd_pcm_read_areas function will be stuck in
> busy
> > loop as below:
> >
> >         avail = snd_pcm_avail_update(pcm); * // here always return
> avail=0,
> > due to the second salve pcm device wasn't ready*
> >         if (avail < 0) {
> >             err = avail;
> >             goto _end;
> >         }
> >         if (avail == 0) {
> >             if (state == SND_PCM_STATE_DRAINING)
> >                 goto _end;
> >             if (pcm->mode & SND_PCM_NONBLOCK) {
> >                 err = -EAGAIN;
> >                 goto _end;
> >             }
> >
> >             err = snd_pcm_wait(pcm, -1); * // return immediately, due to
> > the master slave pcm was ready for read.*
> >             if (err < 0)
> >                 break;
> >             goto _again; *// stuck in busy loop !! again and again until
> > the second pcm data was ready !!!*
> >
> >         }
> >
> > it seemed that the root cause is that the two devices have obvious
> > interrupt period gap , and we also found that this issue can be easily
> > reproduced on our device under low memory case.
> >
> > Currently we monitor this gap and return error to up layer to
> > close-and-reopen device to fix this issue.
> > So I wonder if there is any good solution ?
>
> I tried to resolve this sync in my latest pcm_multi updates (all are in
> 1.1.9
> already). Could you trace, why snd_pcm_wait() does not really wait for the
> slave when avail == 0? There should not be the busy loop. The
> snd_pcm_multi_may_wait_for_avail_min() callback should be called inside the
> multi plugin.
>
>                                 Jaroslav
>
> --
> Jaroslav Kysela <perex at perex.cz>
> Linux Sound Maintainer; ALSA Project; Red Hat, Inc.
>


-- 
BR,

eleven_xiang


More information about the Alsa-devel mailing list