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 */