From: Takashi Iwai <tiwai@suse.de>
To: Stas Sergeev <stsp@aknet.ru>
Cc: alsa-devel@alsa-project.org
Subject: Re: snd_pcsp locking mess
Date: Wed, 28 May 2008 12:13:44 +0200 [thread overview]
Message-ID: <s5hprr6u46f.wl%tiwai@suse.de> (raw)
In-Reply-To: <483C477D.2000207@aknet.ru>
At Tue, 27 May 2008 21:40:13 +0400,
Stas Sergeev wrote:
>
> Hello.
>
> Takashi Iwai wrote:
> > Well, let's take a look back how the callbacks are called.
> > The callbacks that are called during PCM running are the following:
> >
> > - hrtimer callback gets called from hrtimer:
> > This updates the pcsp port and updates the PCM pointer.
> >
> > - PCM pointer callback:
> > This returns the current PCM pointer
> >
> > So, actually between these calls, we have only one thing to protect -
> > the PCM pointer. The DMA-buffer readiness is necessary only for
> > hrtimer callback.
> OK.
>
> > And, in addition, we need to call somewhere snd_pcm_period_elapsed()
> > when the period is finished. This can be done in a tasklet.
> What is the difference between calling
> everything in softirq (current solution)
> and calling snd_pcm_period_elapsed() in
> a tasklet, with the rest in a hardirq
> context? What will this solve?
Think just like the old-good bottomhalf.
The register flip with hrtimer callback is definitely a fast path, so
it should be called inside the hard irq.
OTOH, the update of the whole PCM via snd_pcm_period_elapsed() is a
slow path. Especially in the case of hrtimer, it brings the lock
mess, too. Thus it's better to put this into a softirq.
Issuing softirq at each hrtimer callback isn't optimal from
performance perspective. For RT-kernels, it doesn't matter, but for
normal kernels, it does.
> > Now, remember that hrtimer is started only via trigger start
> > callback. That is, hrtimer callback isn called first after PCM is
> > actually started; hence the DMA buffer is ready when it's called.
> >
> > Then, if we assure that the DMA buffer isn't changed and the PCM
> > substream still exists during hrtimer callback (and/or its execution
> > finishes), hrtimer callback can safely run without *any* lock.
> OK so how do you protect the PCM pointer
> after all? Even in your example you use
> the chip->substream_lock for that (why?),
Because the pointer callback and the hrtimer callback can race about
chip->playback_ptr. The lock is simply to protect it. Don't take it
as a PCM substream lock.
It can be implemened even without a lock, e.g. using a simple barrier,
though. I was just too lazy.
> so it doesn't look like you run a callback
> without any lock at all.
You don't need a lock for the PCM callback itself. The pointer
callback is called inside the PCM substream lock.
> > This is pretty easy. We just need to add appropriate calls to
> > synchronize the finish of hrtimer (and tasklet) at each place that can
> > change the DMA buffers.
> I wonder if this is SMP-safe (comments
> below).
>
> > +/*
> > + * Force to stop and sync the stream
> > + */
> > +void pcsp_sync_stop(struct snd_pcsp *chip)
> > +{
> > + local_irq_disable();
> So what will happen if the timer callback
> is executing on another CPU at that point?
That doesn't matter, because this irqsave is needed just for
i8253_lock in pcsp_stop_playing() (as it doesn't save irq).
> > + pcsp_stop_playing(chip);
> This will set chip->timer_active to 0,
> but who knows if the callback on another
> CPU have already passed the check or not?
If it passed, then we simply wait until the next hrtimer callback
finished. That's what hrtimer_cancel() does. So, after that, it is
guaranteed that neither hrtimer and tasklet remains.
> > + local_irq_enable();
> > + hrtimer_cancel(&chip->timer);
> > + tasklet_kill(&pcsp_pcm_tasklet);
> Ouch, IIRC all three are discouraged to
> use...
Really? Any pointer?
> I (hopefully) now understand the logic
> you are trying to explain, and I don't
> think it is completely trouble-free (I
> may be wrong of course, but certainly
> it won't be straightforward for every
> reader why is that code correct).
> So the question is still why not to
> simply use snd_pcm_stream_lock().
Because the substream lock isn't necessary! It just makes things more
complicated -- if we take substream lock, AB/BA deadlocks occur again.
> And
> if right now it is barely usefull, then
> why it can't be improved to simply not
> require a second lock that guards a
> substream itself?
Because it won't be simpler, as you already tried.
Takashi
next prev parent reply other threads:[~2008-05-28 10:13 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20080518172258.D0DFB108060@picon.linux-foundation.org>
2008-05-18 18:20 ` snd_pcsp locking mess Stas Sergeev
2008-05-19 5:50 ` Takashi Iwai
2008-05-19 17:01 ` Stas Sergeev
2008-05-21 12:33 ` Takashi Iwai
2008-05-22 20:28 ` Stas Sergeev
2008-05-23 10:51 ` Takashi Iwai
2008-05-27 13:46 ` Stas Sergeev
2008-05-27 13:47 ` Stas Sergeev
2008-05-27 15:50 ` Takashi Iwai
2008-05-27 17:40 ` Stas Sergeev
2008-05-28 10:13 ` Takashi Iwai [this message]
2008-05-28 20:08 ` Stas Sergeev
2008-05-29 6:03 ` Takashi Iwai
2008-05-29 17:07 ` Stas Sergeev
2008-06-02 9:36 ` Takashi Iwai
2008-08-21 8:06 ` Stas Sergeev
2008-08-21 9:06 ` Takashi Iwai
2008-08-21 10:25 ` Stas Sergeev
2008-10-20 13:05 ` Takashi Iwai
2008-10-20 21:51 ` Stas Sergeev
2008-10-21 6:27 ` Takashi Iwai
2008-10-21 7:08 ` Stas Sergeev
2008-10-21 7:16 ` Takashi Iwai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=s5hprr6u46f.wl%tiwai@suse.de \
--to=tiwai@suse.de \
--cc=alsa-devel@alsa-project.org \
--cc=stsp@aknet.ru \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox