2011-07-22 13:14:57     Memory Leak in Audio Path

Document created by Aaronwu Employee on Aug 27, 2013
Version 1Show Document
  • View in full screen mode

2011-07-22 13:14:57     Memory Leak in Audio Path

Cameron Barfield (UNITED STATES)

Message: 102618   

 

I'm running 2010R1 kernel and distro (I pulled the latest from git about 1500PDT yesterday) on a custom board based on a BF527-EZKIT (v2) and I've noticed a memory leak somewhere in the audio path. I'm using the BF527C's "internal" codec (SSM2602) connected over TWI/I2S on SPORT0.

 

I first noticed the leak when running a customer application based on Linphone/mediastream. Every time a handle to the soundcard was closed after data was written, I was losing memory. If I never closed the handle to the soundcard, I could write data all day long with no memory loss. I could also open and close the handle to the sound card all day long as long as I never wrote any data to it.

 

I wrote a simple script to play a WAV file via aplay and check the memory after each play. You can see that I'm losing 132 bytes each time I play the WAV file (which is 12,524 bytes)

 

This leak does not exist under 2009R1 with a BF537 and AD1980B codec.

 

Since ALSA is the same version as it was in the 2009R1 distro (1.0.18) and the alsa-utils are the same, I'm presuming that the memory leak lies somewhere in the either the SPORT driver, the SSM2602 driver, the DMA driver or the TWI driver.

 

Here's the script and its output:

 

 

 

root:/test> ls -al

drwxr-xr-x    2 root     root             0 Feb 28 01:03 .

drwxr-xr-x   15 root     root             0 Feb 28 01:03 ..

-rw-r--r--    1 root     root         12524 Feb 28 01:02 d.wav

-rwxr-xr-x    1 root     root            68 Feb 28 01:03 loop.sh

root:/test> cat loop.sh

 

#!/bin/sh

 

while true

do

        aplay d.wav

        sleep 1

        free

        sleep 1

done

 

root:/test> free

             total         used         free       shared      buffers

Mem:         61952        10416        51536            0            0

-/+ buffers:              10416        51536

 

 

root:/test> ./loop.sh

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

             total         used         free       shared      buffers

Mem:         61952        10792        51160            0            0

-/+ buffers:              10792        51160

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

             total         used         free       shared      buffers

Mem:         61952        10924        51028            0            0

-/+ buffers:              10924        51028

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

             total         used         free       shared      buffers

Mem:         61952        11056        50896            0            0

-/+ buffers:              11056        50896

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

             total         used         free       shared      buffers

Mem:         61952        11188        50764            0            0

-/+ buffers:              11188        50764

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

             total         used         free       shared      buffers

Mem:         61952        11320        50632            0            0

-/+ buffers:              11320        50632

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

             total         used         free       shared      buffers

Mem:         61952        11452        50500            0            0

-/+ buffers:              11452        50500

 

 

 

 

Fast forward five minutes

 

 

 

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

             total         used         free       shared      buffers

Mem:         61952        28088        33864            0            0

-/+ buffers:              28088        33864

 

 

Fast forward another 9 minutes or so

 

 

 

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

             total         used         free       shared      buffers

Mem:         61952        49468        12484            0            0

-/+ buffers:              49468        12484

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

             total         used         free       shared      buffers

Mem:         61952        49600        12352            0            0

-/+ buffers:              49600        12352

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

             total         used         free       shared      buffers

Mem:         61952        49732        12220            0            0

-/+ buffers:              49732        12220

 

 

Fast forward another 5 minutes or so

 

 

 

 

 

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

             total         used         free       shared      buffers

Mem:         61952        56048         5904            0            0

-/+ buffers:              56048         5904

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

snd_pcm_update_hw_ptr0: 6 callbacks suppressed

Allocation of length 36864 from process 1955 (aplay) failed

DMA per-cpu:

CPU    0: hi:    0, btch:   1 usd:   0

active_anon:0 inactive_anon:0 isolated_anon:0

active_file:303 inactive_file:11154 isolated_file:0

unevictable:1335 dirty:0 writeback:0 unstable:0

free:1033 slab_reclaimable:226 slab_unreclaimable:321

mapped:0 shmem:0 pagetables:0 bounce:0

DMA free:4132kB min:4096kB low:5120kB high:6144kB active_anon:0kB inactive_anon:0kB active_file:1212kB inactive_file:44616kB unevictable:5340kB isolated(anon):0kB isolated(file):0kB preso

lowmem_reserve[]: 0 0 0

DMA: 9*4kB 4*8kB 2*16kB 2*32kB 0*64kB 1*128kB 1*256kB 1*512kB 1*1024kB 1*2048kB 0*4096kB 0*8192kB 0*16384kB 0*32768kB = 4132kB

1407 total pagecache pages

ALSA lib /home/cameron/src/blackfin/uclinux-dist/lib/alsa-lib/alsa-lib-1.0.18/src/pcm/pcm_mmap.c:422:(snd_pcm_mmap) malloc failed: Cannot allocate memory

aplay: set_params:965: Unable to install hw params:

ACCESS:  RW_INTERLEAVED

FORMAT:  S16_LE

SUBFORMAT:  STD

SAMPLE_BITS: 16

FRAME_BITS: 16

CHANNELS: 1

RATE: 8000

PERIOD_TIME: (21333 21334)

PERIOD_SIZE: (170 171)

PERIOD_BYTES: (340 342)

PERIODS: (15 17)

BUFFER_TIME: 341250

BUFFER_SIZE: 2730

BUFFER_BYTES: 5460

TICK_TIME: 0

            total         used         free       shared      buffers

Mem:         61952        56184         5768            0            0

-/+ buffers:              56184         5768

 

app.config

kernel.config

toplevel.config

QuoteReplyEditDelete

 

 

2011-07-28 23:00:03     Re: Memory Leak in Audio Path

Scott Jiang (CHINA)

Message: 102707   

 

Update status: confirm this bug in 2010R1, but it doesn't exist in latest trunk. Only find this bug in i2s pcm, tdm pcm don't have. Actually the memory leak is 128K not 132 bytes, so it must be a big buffer. Device drivers and sport driver only allocate dma buffer which you can't see through free command. It seems caused by ALSA framework, need more time to find root cause.

QuoteReplyEditDelete

 

 

2011-07-31 16:35:04     Re: Memory Leak in Audio Path

Rob Maris (GERMANY)

Message: 102733   

 

I can confirm Camerons findings (roughly). The leak occured with 2.6.34.7 (I'm using trunk based own branches, but it comes close to 2010R1). The previous own release based on 2.6.28.10 (approx. 2009 release) did not have these problems. Currently, first tests with 2.6.38.1show better figures, but tests are still going on.

QuoteReplyEditDelete

 

 

2011-08-01 03:51:46     Re: Memory Leak in Audio Path

Scott Jiang (CHINA)

Message: 102742   

 

Hi Cameron,

 

Give you a workaround if you are urgent. First modify linux/sound/soc/blackfin/bf5xx-i2s-pcm.c, then modify uclinux/lib/alsa-lib/alsa-lib-1.0.18/src/conf/cards/SSM2602.conf.

 

Index: bf5xx-i2s-pcm.c

===================================================================

--- bf5xx-i2s-pcm.c     (revision 9517)

+++ bf5xx-i2s-pcm.c     (working copy)

@@ -51,8 +51,6 @@

 

static const struct snd_pcm_hardware bf5xx_pcm_hardware = {

        .info                   = SNDRV_PCM_INFO_INTERLEAVED |

-                                  SNDRV_PCM_INFO_MMAP |

-                                  SNDRV_PCM_INFO_MMAP_VALID |

                                   SNDRV_PCM_INFO_BLOCK_TRANSFER,

        .formats                = SNDRV_PCM_FMTBIT_S16_LE |

                                   SNDRV_PCM_FMTBIT_S24_LE |

@@ -194,6 +192,25 @@

        return 0 ;

}

 

+static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,

+                       snd_pcm_uframes_t pos, void *buf, snd_pcm_uframes_t count)

+{

+       struct snd_pcm_runtime *runtime = substream->runtime;

+       u32 *src, *dst;

+

+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {

+               src = buf;

+               dst = (u32 *)runtime->dma_area + pos;

+       } else {

+               src = (u32 *)runtime->dma_area + pos;

+               dst = buf;

+       }

+       while (count--)

+               *dst++ = *src++;

+

+       return 0;

+}

+

static struct snd_pcm_ops bf5xx_pcm_i2s_ops = {

        .open           = bf5xx_pcm_open,

        .ioctl          = snd_pcm_lib_ioctl,

@@ -202,7 +219,7 @@

        .prepare        = bf5xx_pcm_prepare,

        .trigger        = bf5xx_pcm_trigger,

        .pointer        = bf5xx_pcm_pointer,

-       .mmap           = bf5xx_pcm_mmap,

+       .copy           = bf5xx_pcm_copy,

};

 

Index: SSM2602.conf

===================================================================

--- SSM2602.conf        (revision 9965)

+++ SSM2602.conf        (working copy)

@@ -3,19 +3,14 @@

        @args.CARD {

                type string

        }

-       type asym

-       playback.pcm {

-               type plug

+       type plug

+       slave.pcm {

+               type mmap_emul

                slave.pcm {

-                       @func concat

-                       strings [ "dmix:CARD=" $CARD ]

+                       type hw

+                       card $CARD

+                       format S16_LE

+                       rate 48000

                }

        }

-       capture.pcm {

-               type plug

-               slave.pcm {

-                       @func concat

-                       strings [ "dsnoop:CARD=" $CARD ]

-               }

-       }

}

QuoteReplyEditDelete

 

 

2011-08-01 18:19:28     Re: Memory Leak in Audio Path

Cameron Barfield (UNITED STATES)

Message: 102752   

 

Thanks, Scott. So far, so good. I've been testing for four and a half hours.

QuoteReplyEditDelete

 

 

2011-08-03 13:12:19     Re: Memory Leak in Audio Path

Cameron Barfield (UNITED STATES)

Message: 102798   

 

The same problem appears when running a BF536 with AD1980 codec (custom board based on the BF537-STAMP board) under 2010R1

 

 

 

root:~> chmod +x loop.sh

root:~> free

              total         used         free       shared      buffers

  Mem:        55080        10720        44360            0            0

root:~> ./loop.sh

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

              total         used         free       shared      buffers

  Mem:        55080        11060        44020            0            0

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

              total         used         free       shared      buffers

  Mem:        55080        11200        43880            0            0

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

              total         used         free       shared      buffers

  Mem:        55080        11332        43748            0            0

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

              total         used         free       shared      buffers

  Mem:        55080        11464        43616            0            0

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

              total         used         free       shared      buffers

  Mem:        55080        11596        43484            0            0

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

              total         used         free       shared      buffers

  Mem:        55080        11728        43352            0            0

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

              total         used         free       shared      buffers

  Mem:        55080        11860        43220            0            0

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

              total         used         free       shared      buffers

  Mem:        55080        11992        43088            0            0

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

              total         used         free       shared      buffers

  Mem:        55080        12124        42956            0            0

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

              total         used         free       shared      buffers

  Mem:        55080        12256        42824            0            0

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

              total         used         free       shared      buffers

  Mem:        55080        12388        42692            0            0

Playing WAVE 'd.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

              total         used         free       shared      buffers

  Mem:        55080        12520        42560            0            0

 

 

Disabling MMAP for SoC AC97 in the kernel config (SND_BF5XX_MMAP_SUPPORT) cleans up the leak, but without MMAP the DMIX plugin for ALSA does not work and it is not possible for two processes to have open handles to the sound chip.

 

Do you have an ETA on getting the MMAP bug fixed?

QuoteReplyEditDelete

 

 

2011-09-06 02:27:00     Re: Memory Leak in Audio Path

Scott Jiang (CHINA)

Message: 103284   

 

Hi Cameron,

 

I am pleased to tell you I have fixed this bug. It is not caused by ALSA nor MM system. It is caused by fs.

 

diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c

index 5ea4ad8..e9f6f9b 100644

--- a/fs/ramfs/file-nommu.c

+++ b/fs/ramfs/file-nommu.c

@@ -112,6 +112,7 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)

                SetPageDirty(page);

 

                unlock_page(page);

+               put_page(page);

        }

 

        return 0;

QuoteReplyEditDelete

 

 

2011-09-06 04:45:27     Re: Memory Leak in Audio Path

Rob Maris (GERMANY)

Message: 103306    Scott, many thanks for getting this. I applied it with my 2.6.34.7

production kernel (which, in fact - evolved to official 2010R1) and it

works. At this time I'll stick to this version until the bug with

concurrent audio playback on one device has been fixed.

For generic info: fix was "officially" applied as per 2.6.38.3

(2011-04-14). I see that you have applied the patch to 2010R1.

QuoteReplyEditDelete

 

 

2011-09-06 14:45:03     Re: Memory Leak in Audio Path

Cameron Barfield (UNITED STATES)

Message: 103310   

 

Thanks, Scott. I was able to confirm that this fixes the memory leak on the SSM2602.

Outcomes