[alsa-devel] Interrupts and kmalloc in alsa modules
Hi all, I am working with an ARM embedded system and I porting an alsa application to that system.
Cirrus (the manufacturer of the board) wrote a generic alsa driver for "their" kernel (a kernel based on the 2.6.8 with some patches) and I ported the module to the vanilla kernel 2.6.19.
The module works fine (play and capture both work), but the function that allocates the memory prints a strange message in the kernel log when the buffers are allocated (the module calls kmalloc, which prints "sleeping function called from invalid context" to the log).
The buffers are allocated when the streams are started, not when the module is loaded, I think this is standard...
The buffers are allocated with the following line:
s->buffers = (audio_buf_t *) kmalloc(sizeof(audio_buf_t) * s->nbfrags, GFP_KERNEL);
When the line here above is executed, slab.c prints the error the kernel log. The error comes from the "might_sleep_if" line:
static inline void cache_alloc_debugcheck_before(struct kmem_cache *cachep, gfp_t flags) { might_sleep_if(flags & __GFP_WAIT); #if DEBUG kmem_flagcheck(cachep, flags); #endif }
Playing with the module, I discovered that if I enable the interrupts before calling kmalloc, the error disappears. I wonder if this is correct, or if something is wrong...
Could someone of you explain to me why I have to enable the interrupts before calling kmalloc? The strange thing is that the module never explicitly turns them off (I attached the file to the mail)
Any help is greatly appreciated ;-) Bye Andrea
____________________________________________________________________________________ Food fight? Enjoy some healthy debate in the Yahoo! Answers Food & Drink Q&A. http://answers.yahoo.com/dir/?link=list&sid=396545367
On 4/10/07, Ciaccia ciacciax@yahoo.com wrote:
Could someone of you explain to me why I have to enable the interrupts before calling kmalloc? The strange thing is that the module never explicitly turns them off (I attached the file to the mail)
I guess you're allocating memory in the trigger callback which is atomic meaning that the ALSA middle layer always calls it with interrupts disabled. It's a bug to call a function that can sleep with interrupts disabled.
The standard way to do it is to allocate your buffers in a callback that can sleep like prepare. See numerous examples in other ALSA drivers.
Of course without seeing your code, this is all guesswork...
Lee
Hi Lee, Your guess is correct. The buffers are allocated in the trigger callback, I attached the module source to the my email but it got lost...?!?
Sorry for that, maybe this time it's better: http://www.pecore.ch/test/ep93xx-i2s.c.txt
Thanks again Andrea
--- Lee Revell rlrevell@joe-job.com wrote:
On 4/10/07, Ciaccia ciacciax@yahoo.com wrote:
Could someone of you explain to me why I have to enable the interrupts before calling kmalloc? The strange thing is that the module never explicitly turns them off (I attached the file to the mail)
I guess you're allocating memory in the trigger callback which is atomic meaning that the ALSA middle layer always calls it with interrupts disabled. It's a bug to call a function that can sleep with interrupts disabled.
The standard way to do it is to allocate your buffers in a callback that can sleep like prepare. See numerous examples in other ALSA drivers.
Of course without seeing your code, this is all guesswork...
Lee
____________________________________________________________________________________ It's here! Your new message! Get new email alerts with the free Yahoo! Toolbar. http://tools.search.yahoo.com/toolbar/features/mail/
On 4/10/07, Ciaccia ciacciax@yahoo.com wrote:
Hi Lee, Your guess is correct. The buffers are allocated in the trigger callback, I attached the module source to the my email but it got lost...?!?
Sorry for that, maybe this time it's better: http://www.pecore.ch/test/ep93xx-i2s.c.txt
OK so allocate them in the prepare callback instead, problem solved. See "Writing an ALSA driver" doc for details.
BTW why does your driver do all that sample format conversion, rather than just exposing the HW supported format and letting alsa-lib do the conversion for you?
Lee
Hi Lee, Thanks a lot for the explanation! Now I understand what's wrong with the module, I must remove the buffer allocation from the trigger and put it somewhere else... You said I should move it in the prepare function, this page http://www.alsa-project.org/~iwai/writing-an-alsa-driver/x639.htm says it should go in the hw_params. What's the best place where to put it?
I did not write the module, so I really don't know why all the sample format conversion code is in the module... How could I fix/improve it and use the sample conversion already available in alsa-lib?
Thanks Bye Andrea
--- Lee Revell rlrevell@joe-job.com wrote:
On 4/10/07, Ciaccia ciacciax@yahoo.com wrote:
Hi Lee, Your guess is correct. The buffers are allocated
in
the trigger callback, I attached the module source
to
the my email but it got lost...?!?
Sorry for that, maybe this time it's better: http://www.pecore.ch/test/ep93xx-i2s.c.txt
OK so allocate them in the prepare callback instead, problem solved. See "Writing an ALSA driver" doc for details.
BTW why does your driver do all that sample format conversion, rather than just exposing the HW supported format and letting alsa-lib do the conversion for you?
Lee
____________________________________________________________________________________ It's here! Your new message! Get new email alerts with the free Yahoo! Toolbar. http://tools.search.yahoo.com/toolbar/features/mail/
At Wed, 11 Apr 2007 00:11:51 -0700 (PDT), Ciaccia wrote:
Hi Lee, Thanks a lot for the explanation! Now I understand what's wrong with the module, I must remove the buffer allocation from the trigger and put it somewhere else... You said I should move it in the prepare function, this page http://www.alsa-project.org/~iwai/writing-an-alsa-driver/x639.htm says it should go in the hw_params. What's the best place where to put it?
The document recommends hw_params callback because prepare callback was atomic in the earlier ALSA version while now it's non-atomic, too. If it's currently in trigger callback, prepare might be slightly easier, I guess.
I did not write the module, so I really don't know why all the sample format conversion code is in the module... How could I fix/improve it and use the sample conversion already available in alsa-lib?
Just drop the whole sample conversion part in the driver and define only the natively supported format in snd_pcm_hardware.formats field. Then the rest necessary thing will be done automatically in alsa-lib.
I still didn't see the code at this moment, so just a guess. I'll review it soon later.
thanks,
Takashi
participants (3)
-
Ciaccia
-
Lee Revell
-
Takashi Iwai