[alsa-devel] snd_array_free - snd: bad kfree when HDA reconfig
Takashi Iwai
tiwai at suse.de
Mon Sep 12 09:46:17 CEST 2011
At Fri, 2 Sep 2011 15:16:28 +0800,
Raymond Yau wrote:
>
> These errors "snd: bad kfree" occur when reconfig HDA from model
> "6stack-dig-fp" to "auto" and vice versa
Doesn't this happen when you unload the device, right?
And, it happens when writing to /sys/class/sound/hwC0D0/clear?
> Is "HD-Audio reconfiguration" still experimental ?
Somehow yet, but mostly it worked for me :)
> BTW, it seem that HDA Digital PCBeep assigned to different input after
> each reconfig
>
> input: HDA Digital PCBeep as /devices/pci0000:00/0000:00:1b.0/input/input7
> input: HDA Digital PCBeep as /devices/pci0000:00/0000:00:1b.0/input/input8
> input: HDA Digital PCBeep as /devices/pci0000:00/0000:00:1b.0/input/input9
This is unavoidable, unfortunately. It's the designed implementation
of input layer.
> ALSA hda_hwdep.c:220: hda-codec: reconfiguring
> snd: bad kfree (called from f8be4636)
Hmm, this is a magic check in external alsa-driver builds.
I guess it's just a bug there -- the override of krealloc() is
missing.
Does the patch below (to alsa-driver tree) fix the problem?
thanks,
Takashi
---
diff --git a/acore/memory_debug.c b/acore/memory_debug.c
index 4527378..0baf9b9 100644
--- a/acore/memory_debug.c
+++ b/acore/memory_debug.c
@@ -128,6 +128,21 @@ void snd_hidden_kfree(const void *obj)
snd_wrapper_kfree(obj);
}
+size_t snd_hidden_ksize(const void *obj)
+{
+ struct snd_alloc_track *t;
+ if (!obj)
+ return 0;
+ t = snd_alloc_track_entry(obj);
+ if (t->magic != KMALLOC_MAGIC) {
+ printk(KERN_WARNING "snd: bad ksize (called from %p)\n",
+ __builtin_return_address(0));
+ dump_stack();
+ return 0;
+ }
+ return t->size;
+}
+
char *snd_hidden_kstrdup(const char *s, gfp_t gfp_flags)
{
int len;
diff --git a/include/adriver.h b/include/adriver.h
index 1418a5e..fe70442 100644
--- a/include/adriver.h
+++ b/include/adriver.h
@@ -892,6 +892,7 @@ void *snd_hidden_kcalloc(size_t n, size_t size, gfp_t flags);
char *snd_hidden_kstrdup(const char *s, gfp_t flags);
char *snd_hidden_kstrndup(const char *s, size_t len, gfp_t flags);
void snd_hidden_kfree(const void *obj);
+size_t snd_hidden_ksize(const void *obj);
static inline void *snd_wrapper_kmalloc(size_t size, gfp_t flags)
{
@@ -907,6 +908,7 @@ static inline void snd_wrapper_kfree(const void *obj)
#define kcalloc(n, size, flags) snd_hidden_kcalloc(n, size, flags)
#define kstrdup(s, flags) snd_hidden_kstrdup(s, flags)
#define kstrndup(s, len, flags) snd_hidden_kstrndup(s, len, flags)
+#define ksize(obj) snd_hidden_ksize(obj)
#define kfree(obj) snd_hidden_kfree(obj)
#define kmalloc_nocheck(size, flags) snd_wrapper_kmalloc(size, flags)
@@ -2000,9 +2002,9 @@ static inline bool flush_delayed_work_sync(struct delayed_work *dwork)
#endif
/* krealloc() wrapper */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)) || defined(CONFIG_SND_DEBUG_MEMORY)
#include <linux/slab.h>
-static inline void *krealloc(const void *p, size_t new_size, gfp_t flags)
+static inline void *snd_compat_krealloc(const void *p, size_t new_size, gfp_t flags)
{
void *n;
if (!p)
@@ -2018,6 +2020,7 @@ static inline void *krealloc(const void *p, size_t new_size, gfp_t flags)
kfree(p);
return n;
}
+#define krealloc(p, s, f) snd_compat_krealloc(p, s, f)
#endif
#endif /* __SOUND_LOCAL_DRIVER_H */
More information about the Alsa-devel
mailing list