Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
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

  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