Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b1d5776d authored by Takashi Iwai's avatar Takashi Iwai Committed by Jaroslav Kysela
Browse files

[ALSA] Remove vmalloc wrapper, kfree_nocheck()



- Remove vmalloc wrapper
- Add release_and_free_resource() to remove kfree_nocheck() from each driver
  and simplify the code

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 93f2e378
Loading
Loading
Loading
Loading
+1 −16
Original line number Diff line number Diff line
@@ -1433,25 +1433,10 @@
        <informalexample>
          <programlisting>
<![CDATA[
  if (chip->res_port) {
          release_resource(chip->res_port);
          kfree_nocheck(chip->res_port);
  }
  release_and_free_resource(chip->res_port);
]]>
          </programlisting>
        </informalexample>

      As you can see, the resource pointer is also to be freed
      via <function>kfree_nocheck()</function> after
      <function>release_resource()</function> is called. You
      cannot use <function>kfree()</function> here, because on ALSA,
      <function>kfree()</function> may be a wrapper to its own
      allocator with the memory debugging. Since the resource pointer
      is allocated externally outside the ALSA, it must be released
      via the native
      <function>kfree()</function>.
      <function>kfree_nocheck()</function> is used for that; it calls
      the native <function>kfree()</function> without wrapper. 
      </para>

      <para>
+1 −8
Original line number Diff line number Diff line
@@ -293,19 +293,13 @@ void *snd_hidden_kmalloc(size_t size, gfp_t flags);
void *snd_hidden_kzalloc(size_t size, gfp_t flags);
void *snd_hidden_kcalloc(size_t n, size_t size, gfp_t flags);
void snd_hidden_kfree(const void *obj);
void *snd_hidden_vmalloc(unsigned long size);
void snd_hidden_vfree(void *obj);
char *snd_hidden_kstrdup(const char *s, gfp_t flags);
#define kmalloc(size, flags) snd_hidden_kmalloc(size, flags)
#define kzalloc(size, flags) snd_hidden_kzalloc(size, flags)
#define kcalloc(n, size, flags) snd_hidden_kcalloc(n, size, flags)
#define kfree(obj) snd_hidden_kfree(obj)
#define vmalloc(size) snd_hidden_vmalloc(size)
#define vfree(obj) snd_hidden_vfree(obj)
#define kmalloc_nocheck(size, flags) snd_wrapper_kmalloc(size, flags)
#define vmalloc_nocheck(size) snd_wrapper_vmalloc(size)
#define kfree_nocheck(obj) snd_wrapper_kfree(obj)
#define vfree_nocheck(obj) snd_wrapper_vfree(obj)
#define kstrdup(s, flags)  snd_hidden_kstrdup(s, flags)
#else
#define snd_memory_init() /*NOP*/
@@ -313,9 +307,7 @@ char *snd_hidden_kstrdup(const char *s, gfp_t flags);
#define snd_memory_info_init() /*NOP*/
#define snd_memory_info_done() /*NOP*/
#define kmalloc_nocheck(size, flags) kmalloc(size, flags)
#define vmalloc_nocheck(size) vmalloc(size)
#define kfree_nocheck(obj) kfree(obj)
#define vfree_nocheck(obj) vfree(obj)
#endif
int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count);
int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count);
@@ -372,6 +364,7 @@ unsigned int snd_dma_pointer(unsigned long dma, unsigned int size);
#endif

/* misc.c */
void release_and_free_resource(struct resource *res);

#ifdef CONFIG_SND_VERBOSE_PRINTK
void snd_verbose_printk(const char *file, int line, const char *format, ...)
+0 −4
Original line number Diff line number Diff line
@@ -55,10 +55,6 @@ void *snd_wrapper_kmalloc(size_t, gfp_t);
#undef kmalloc
void snd_wrapper_kfree(const void *);
#undef kfree
void *snd_wrapper_vmalloc(size_t);
#undef vmalloc
void snd_wrapper_vfree(void *);
#undef vfree
#endif

#endif /* __SOUND_DRIVER_H */
+0 −53
Original line number Diff line number Diff line
@@ -47,19 +47,14 @@ struct snd_alloc_track {
#define snd_alloc_track_entry(obj) (struct snd_alloc_track *)((char*)obj - (unsigned long)((struct snd_alloc_track *)0)->data)

static long snd_alloc_kmalloc;
static long snd_alloc_vmalloc;
static LIST_HEAD(snd_alloc_kmalloc_list);
static LIST_HEAD(snd_alloc_vmalloc_list);
static DEFINE_SPINLOCK(snd_alloc_kmalloc_lock);
static DEFINE_SPINLOCK(snd_alloc_vmalloc_lock);
#define KMALLOC_MAGIC 0x87654321
#define VMALLOC_MAGIC 0x87654320
static snd_info_entry_t *snd_memory_info_entry;

void __init snd_memory_init(void)
{
	snd_alloc_kmalloc = 0;
	snd_alloc_vmalloc = 0;
}

void snd_memory_done(void)
@@ -69,8 +64,6 @@ void snd_memory_done(void)

	if (snd_alloc_kmalloc > 0)
		snd_printk(KERN_ERR "Not freed snd_alloc_kmalloc = %li\n", snd_alloc_kmalloc);
	if (snd_alloc_vmalloc > 0)
		snd_printk(KERN_ERR "Not freed snd_alloc_vmalloc = %li\n", snd_alloc_vmalloc);
	list_for_each_prev(head, &snd_alloc_kmalloc_list) {
		t = list_entry(head, struct snd_alloc_track, list);
		if (t->magic != KMALLOC_MAGIC) {
@@ -79,14 +72,6 @@ void snd_memory_done(void)
		}
		snd_printk(KERN_ERR "kmalloc(%ld) from %p not freed\n", (long) t->size, t->caller);
	}
	list_for_each_prev(head, &snd_alloc_vmalloc_list) {
		t = list_entry(head, struct snd_alloc_track, list);
		if (t->magic != VMALLOC_MAGIC) {
			snd_printk(KERN_ERR "Corrupted vmalloc\n");
			break;
		}
		snd_printk(KERN_ERR "vmalloc(%ld) from %p not freed\n", (long) t->size, t->caller);
	}
}

static void *__snd_kmalloc(size_t size, gfp_t flags, void *caller)
@@ -153,43 +138,6 @@ void snd_hidden_kfree(const void *obj)
	snd_wrapper_kfree(obj);
}

void *snd_hidden_vmalloc(unsigned long size)
{
	void *ptr;
	ptr = snd_wrapper_vmalloc(size + sizeof(struct snd_alloc_track));
	if (ptr) {
		struct snd_alloc_track *t = (struct snd_alloc_track *)ptr;
		t->magic = VMALLOC_MAGIC;
		t->caller = __builtin_return_address(0);
		spin_lock(&snd_alloc_vmalloc_lock);
		list_add_tail(&t->list, &snd_alloc_vmalloc_list);
		spin_unlock(&snd_alloc_vmalloc_lock);
		t->size = size;
		snd_alloc_vmalloc += size;
		ptr = t->data;
	}
	return ptr;
}

void snd_hidden_vfree(void *obj)
{
	struct snd_alloc_track *t;
	if (obj == NULL)
		return;
	t = snd_alloc_track_entry(obj);
	if (t->magic != VMALLOC_MAGIC) {
		snd_printk(KERN_ERR "bad vfree (called from %p)\n", __builtin_return_address(0));
		return;
	}
	spin_lock(&snd_alloc_vmalloc_lock);
	list_del(&t->list);
	spin_unlock(&snd_alloc_vmalloc_lock);
	t->magic = 0;
	snd_alloc_vmalloc -= t->size;
	obj = t;
	snd_wrapper_vfree(obj);
}

char *snd_hidden_kstrdup(const char *s, gfp_t flags)
{
	int len;
@@ -207,7 +155,6 @@ char *snd_hidden_kstrdup(const char *s, gfp_t flags)
static void snd_memory_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
{
	snd_iprintf(buffer, "kmalloc: %li bytes\n", snd_alloc_kmalloc);
	snd_iprintf(buffer, "vmalloc: %li bytes\n", snd_alloc_vmalloc);
}

int __init snd_memory_info_init(void)
+9 −0
Original line number Diff line number Diff line
@@ -23,8 +23,17 @@
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/ioport.h>
#include <sound/core.h>

void release_and_free_resource(struct resource *res)
{
	if (res) {
		release_resource(res);
		kfree_nocheck(res);
	}
}

#ifdef CONFIG_SND_VERBOSE_PRINTK
void snd_verbose_printk(const char *file, int line, const char *format, ...)
{
Loading