diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-08-16 18:42:58 +0100 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-08-16 18:42:58 +0100 |
commit | e4862f2f6f5653dfb67f3ba2b6f0bc74516ed51a (patch) | |
tree | 1db5a0540a4eecfad9b7daee476b985e82ddc810 /lib/scatterlist.c | |
parent | ec62dbd7eb8e3dddb221da89ecbcea0fc3dee8c1 (diff) | |
parent | b2c1e07b81a126e5846dfc3d36f559d861df59f4 (diff) |
Merge branch 'for-2.6.36' into for-2.6.37
Fairly simple conflicts, the most serious ones are the i.MX ones which I
suspect now need another rename.
Conflicts:
arch/arm/mach-mx2/clock_imx27.c
arch/arm/mach-mx2/devices.c
arch/arm/mach-omap2/board-rx51-peripherals.c
arch/arm/mach-omap2/board-zoom2.c
sound/soc/fsl/mpc5200_dma.c
sound/soc/fsl/mpc5200_dma.h
sound/soc/fsl/mpc8610_hpcd.c
sound/soc/pxa/spitz.c
Diffstat (limited to 'lib/scatterlist.c')
-rw-r--r-- | lib/scatterlist.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/lib/scatterlist.c b/lib/scatterlist.c index 9afa25b52a8..a5ec42868f9 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -10,6 +10,7 @@ #include <linux/slab.h> #include <linux/scatterlist.h> #include <linux/highmem.h> +#include <linux/kmemleak.h> /** * sg_next - return the next scatterlist entry in a list @@ -115,17 +116,29 @@ EXPORT_SYMBOL(sg_init_one); */ static struct scatterlist *sg_kmalloc(unsigned int nents, gfp_t gfp_mask) { - if (nents == SG_MAX_SINGLE_ALLOC) - return (struct scatterlist *) __get_free_page(gfp_mask); - else + if (nents == SG_MAX_SINGLE_ALLOC) { + /* + * Kmemleak doesn't track page allocations as they are not + * commonly used (in a raw form) for kernel data structures. + * As we chain together a list of pages and then a normal + * kmalloc (tracked by kmemleak), in order to for that last + * allocation not to become decoupled (and thus a + * false-positive) we need to inform kmemleak of all the + * intermediate allocations. + */ + void *ptr = (void *) __get_free_page(gfp_mask); + kmemleak_alloc(ptr, PAGE_SIZE, 1, gfp_mask); + return ptr; + } else return kmalloc(nents * sizeof(struct scatterlist), gfp_mask); } static void sg_kfree(struct scatterlist *sg, unsigned int nents) { - if (nents == SG_MAX_SINGLE_ALLOC) + if (nents == SG_MAX_SINGLE_ALLOC) { + kmemleak_free(sg); free_page((unsigned long) sg); - else + } else kfree(sg); } |