]> git.karo-electronics.de Git - linux-beck.git/commitdiff
ALSA: firewire-lib: optimize packet flushing
authorClemens Ladisch <clemens@ladisch.de>
Sun, 13 May 2012 17:07:22 +0000 (19:07 +0200)
committerTakashi Iwai <tiwai@suse.de>
Mon, 14 May 2012 08:43:43 +0000 (10:43 +0200)
Trying to flush completed packets is pointless when the pointer
callback was called from the packet completion callback; avoid it.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/firewire/amdtp.c
sound/firewire/amdtp.h

index c2685fbd73666635e579e3a5d5bc58fbc68795f0..ea995af6d049ec63b86f8fb59cf374640db9cc56 100644 (file)
@@ -178,6 +178,7 @@ void amdtp_out_stream_pcm_prepare(struct amdtp_out_stream *s)
        tasklet_kill(&s->period_tasklet);
        s->pcm_buffer_pointer = 0;
        s->pcm_period_pointer = 0;
+       s->pointer_flush = true;
 }
 EXPORT_SYMBOL(amdtp_out_stream_pcm_prepare);
 
@@ -393,6 +394,7 @@ static void queue_out_packet(struct amdtp_out_stream *s, unsigned int cycle)
                s->pcm_period_pointer += data_blocks;
                if (s->pcm_period_pointer >= pcm->runtime->period_size) {
                        s->pcm_period_pointer -= pcm->runtime->period_size;
+                       s->pointer_flush = false;
                        tasklet_hi_schedule(&s->period_tasklet);
                }
        }
@@ -539,7 +541,11 @@ EXPORT_SYMBOL(amdtp_out_stream_start);
  */
 unsigned long amdtp_out_stream_pcm_pointer(struct amdtp_out_stream *s)
 {
-       fw_iso_context_flush_completions(s->context);
+       /* this optimization is allowed to be racy */
+       if (s->pointer_flush)
+               fw_iso_context_flush_completions(s->context);
+       else
+               s->pointer_flush = true;
 
        return ACCESS_ONCE(s->pcm_buffer_pointer);
 }
index 3f13ff63c5d245072e9671f029665903ee4c12d6..b680c5ef01d694468f3b2736f357e49a09d50bf3 100644 (file)
@@ -68,6 +68,7 @@ struct amdtp_out_stream {
 
        unsigned int pcm_buffer_pointer;
        unsigned int pcm_period_pointer;
+       bool pointer_flush;
 };
 
 int amdtp_out_stream_init(struct amdtp_out_stream *s, struct fw_unit *unit,