aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRasmus Villemoes <linux@rasmusvillemoes.dk>2016-05-19 20:10:55 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-19 22:12:14 -0400
commit48a270554a3251681ae11173f2fd6389d943e183 (patch)
treeb650279a0e0c255f28ad819593a3c86328821571
parentd64e85d3e1c59c3664b9ec1183052ec4641ea1e2 (diff)
include/linux: apply __malloc attribute
Attach the malloc attribute to a few allocation functions. This helps gcc generate better code by telling it that the return value doesn't alias any existing pointers (which is even more valuable given the pessimizations implied by -fno-strict-aliasing). A simple example of what this allows gcc to do can be seen by looking at the last part of drm_atomic_helper_plane_reset: plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL); if (plane->state) { plane->state->plane = plane; plane->state->rotation = BIT(DRM_ROTATE_0); } which compiles to e8 99 bf d6 ff callq ffffffff8116d540 <kmem_cache_alloc_trace> 48 85 c0 test %rax,%rax 48 89 83 40 02 00 00 mov %rax,0x240(%rbx) 74 11 je ffffffff814015c4 <drm_atomic_helper_plane_reset+0x64> 48 89 18 mov %rbx,(%rax) 48 8b 83 40 02 00 00 mov 0x240(%rbx),%rax [*] c7 40 40 01 00 00 00 movl $0x1,0x40(%rax) With this patch applied, the instruction at [*] is elided, since the store to plane->state->plane is known to not alter the value of plane->state. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk> Cc: Christoph Lameter <cl@linux.com> Cc: Pekka Enberg <penberg@kernel.org> Cc: David Rientjes <rientjes@google.com> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> Cc: Andi Kleen <ak@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--include/linux/bootmem.h16
-rw-r--r--include/linux/device.h12
-rw-r--r--include/linux/kernel.h4
-rw-r--r--include/linux/mempool.h3
-rw-r--r--include/linux/slab.h16
-rw-r--r--include/linux/string.h2
6 files changed, 27 insertions, 26 deletions
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index 35b22f94d2d2..f9be32691718 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -83,34 +83,34 @@ extern void *__alloc_bootmem(unsigned long size,
83 unsigned long goal); 83 unsigned long goal);
84extern void *__alloc_bootmem_nopanic(unsigned long size, 84extern void *__alloc_bootmem_nopanic(unsigned long size,
85 unsigned long align, 85 unsigned long align,
86 unsigned long goal); 86 unsigned long goal) __malloc;
87extern void *__alloc_bootmem_node(pg_data_t *pgdat, 87extern void *__alloc_bootmem_node(pg_data_t *pgdat,
88 unsigned long size, 88 unsigned long size,
89 unsigned long align, 89 unsigned long align,
90 unsigned long goal); 90 unsigned long goal) __malloc;
91void *__alloc_bootmem_node_high(pg_data_t *pgdat, 91void *__alloc_bootmem_node_high(pg_data_t *pgdat,
92 unsigned long size, 92 unsigned long size,
93 unsigned long align, 93 unsigned long align,
94 unsigned long goal); 94 unsigned long goal) __malloc;
95extern void *__alloc_bootmem_node_nopanic(pg_data_t *pgdat, 95extern void *__alloc_bootmem_node_nopanic(pg_data_t *pgdat,
96 unsigned long size, 96 unsigned long size,
97 unsigned long align, 97 unsigned long align,
98 unsigned long goal); 98 unsigned long goal) __malloc;
99void *___alloc_bootmem_node_nopanic(pg_data_t *pgdat, 99void *___alloc_bootmem_node_nopanic(pg_data_t *pgdat,
100 unsigned long size, 100 unsigned long size,
101 unsigned long align, 101 unsigned long align,
102 unsigned long goal, 102 unsigned long goal,
103 unsigned long limit); 103 unsigned long limit) __malloc;
104extern void *__alloc_bootmem_low(unsigned long size, 104extern void *__alloc_bootmem_low(unsigned long size,
105 unsigned long align, 105 unsigned long align,
106 unsigned long goal); 106 unsigned long goal) __malloc;
107void *__alloc_bootmem_low_nopanic(unsigned long size, 107void *__alloc_bootmem_low_nopanic(unsigned long size,
108 unsigned long align, 108 unsigned long align,
109 unsigned long goal); 109 unsigned long goal) __malloc;
110extern void *__alloc_bootmem_low_node(pg_data_t *pgdat, 110extern void *__alloc_bootmem_low_node(pg_data_t *pgdat,
111 unsigned long size, 111 unsigned long size,
112 unsigned long align, 112 unsigned long align,
113 unsigned long goal); 113 unsigned long goal) __malloc;
114 114
115#ifdef CONFIG_NO_BOOTMEM 115#ifdef CONFIG_NO_BOOTMEM
116/* We are using top down, so it is safe to use 0 here */ 116/* We are using top down, so it is safe to use 0 here */
diff --git a/include/linux/device.h b/include/linux/device.h
index b130304f9b1b..ca90ad8bcd61 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -609,14 +609,14 @@ typedef int (*dr_match_t)(struct device *dev, void *res, void *match_data);
609 609
610#ifdef CONFIG_DEBUG_DEVRES 610#ifdef CONFIG_DEBUG_DEVRES
611extern void *__devres_alloc_node(dr_release_t release, size_t size, gfp_t gfp, 611extern void *__devres_alloc_node(dr_release_t release, size_t size, gfp_t gfp,
612 int nid, const char *name); 612 int nid, const char *name) __malloc;
613#define devres_alloc(release, size, gfp) \ 613#define devres_alloc(release, size, gfp) \
614 __devres_alloc_node(release, size, gfp, NUMA_NO_NODE, #release) 614 __devres_alloc_node(release, size, gfp, NUMA_NO_NODE, #release)
615#define devres_alloc_node(release, size, gfp, nid) \ 615#define devres_alloc_node(release, size, gfp, nid) \
616 __devres_alloc_node(release, size, gfp, nid, #release) 616 __devres_alloc_node(release, size, gfp, nid, #release)
617#else 617#else
618extern void *devres_alloc_node(dr_release_t release, size_t size, gfp_t gfp, 618extern void *devres_alloc_node(dr_release_t release, size_t size, gfp_t gfp,
619 int nid); 619 int nid) __malloc;
620static inline void *devres_alloc(dr_release_t release, size_t size, gfp_t gfp) 620static inline void *devres_alloc(dr_release_t release, size_t size, gfp_t gfp)
621{ 621{
622 return devres_alloc_node(release, size, gfp, NUMA_NO_NODE); 622 return devres_alloc_node(release, size, gfp, NUMA_NO_NODE);
@@ -648,12 +648,12 @@ extern void devres_remove_group(struct device *dev, void *id);
648extern int devres_release_group(struct device *dev, void *id); 648extern int devres_release_group(struct device *dev, void *id);
649 649
650/* managed devm_k.alloc/kfree for device drivers */ 650/* managed devm_k.alloc/kfree for device drivers */
651extern void *devm_kmalloc(struct device *dev, size_t size, gfp_t gfp); 651extern void *devm_kmalloc(struct device *dev, size_t size, gfp_t gfp) __malloc;
652extern __printf(3, 0) 652extern __printf(3, 0)
653char *devm_kvasprintf(struct device *dev, gfp_t gfp, const char *fmt, 653char *devm_kvasprintf(struct device *dev, gfp_t gfp, const char *fmt,
654 va_list ap); 654 va_list ap) __malloc;
655extern __printf(3, 4) 655extern __printf(3, 4)
656char *devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...); 656char *devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...) __malloc;
657static inline void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp) 657static inline void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp)
658{ 658{
659 return devm_kmalloc(dev, size, gfp | __GFP_ZERO); 659 return devm_kmalloc(dev, size, gfp | __GFP_ZERO);
@@ -671,7 +671,7 @@ static inline void *devm_kcalloc(struct device *dev,
671 return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO); 671 return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO);
672} 672}
673extern void devm_kfree(struct device *dev, void *p); 673extern void devm_kfree(struct device *dev, void *p);
674extern char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp); 674extern char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) __malloc;
675extern void *devm_kmemdup(struct device *dev, const void *src, size_t len, 675extern void *devm_kmemdup(struct device *dev, const void *src, size_t len,
676 gfp_t gfp); 676 gfp_t gfp);
677 677
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 2f7775e229b0..cc7398287fdd 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -412,9 +412,9 @@ extern __printf(3, 4)
412int scnprintf(char *buf, size_t size, const char *fmt, ...); 412int scnprintf(char *buf, size_t size, const char *fmt, ...);
413extern __printf(3, 0) 413extern __printf(3, 0)
414int vscnprintf(char *buf, size_t size, const char *fmt, va_list args); 414int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
415extern __printf(2, 3) 415extern __printf(2, 3) __malloc
416char *kasprintf(gfp_t gfp, const char *fmt, ...); 416char *kasprintf(gfp_t gfp, const char *fmt, ...);
417extern __printf(2, 0) 417extern __printf(2, 0) __malloc
418char *kvasprintf(gfp_t gfp, const char *fmt, va_list args); 418char *kvasprintf(gfp_t gfp, const char *fmt, va_list args);
419extern __printf(2, 0) 419extern __printf(2, 0)
420const char *kvasprintf_const(gfp_t gfp, const char *fmt, va_list args); 420const char *kvasprintf_const(gfp_t gfp, const char *fmt, va_list args);
diff --git a/include/linux/mempool.h b/include/linux/mempool.h
index 69b6951e8fd2..b1086c936507 100644
--- a/include/linux/mempool.h
+++ b/include/linux/mempool.h
@@ -5,6 +5,7 @@
5#define _LINUX_MEMPOOL_H 5#define _LINUX_MEMPOOL_H
6 6
7#include <linux/wait.h> 7#include <linux/wait.h>
8#include <linux/compiler.h>
8 9
9struct kmem_cache; 10struct kmem_cache;
10 11
@@ -31,7 +32,7 @@ extern mempool_t *mempool_create_node(int min_nr, mempool_alloc_t *alloc_fn,
31 32
32extern int mempool_resize(mempool_t *pool, int new_min_nr); 33extern int mempool_resize(mempool_t *pool, int new_min_nr);
33extern void mempool_destroy(mempool_t *pool); 34extern void mempool_destroy(mempool_t *pool);
34extern void * mempool_alloc(mempool_t *pool, gfp_t gfp_mask); 35extern void *mempool_alloc(mempool_t *pool, gfp_t gfp_mask) __malloc;
35extern void mempool_free(void *element, mempool_t *pool); 36extern void mempool_free(void *element, mempool_t *pool);
36 37
37/* 38/*
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 508bd827e6dc..aeb3e6d00a66 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -315,8 +315,8 @@ static __always_inline int kmalloc_index(size_t size)
315} 315}
316#endif /* !CONFIG_SLOB */ 316#endif /* !CONFIG_SLOB */
317 317
318void *__kmalloc(size_t size, gfp_t flags) __assume_kmalloc_alignment; 318void *__kmalloc(size_t size, gfp_t flags) __assume_kmalloc_alignment __malloc;
319void *kmem_cache_alloc(struct kmem_cache *, gfp_t flags) __assume_slab_alignment; 319void *kmem_cache_alloc(struct kmem_cache *, gfp_t flags) __assume_slab_alignment __malloc;
320void kmem_cache_free(struct kmem_cache *, void *); 320void kmem_cache_free(struct kmem_cache *, void *);
321 321
322/* 322/*
@@ -339,8 +339,8 @@ static __always_inline void kfree_bulk(size_t size, void **p)
339} 339}
340 340
341#ifdef CONFIG_NUMA 341#ifdef CONFIG_NUMA
342void *__kmalloc_node(size_t size, gfp_t flags, int node) __assume_kmalloc_alignment; 342void *__kmalloc_node(size_t size, gfp_t flags, int node) __assume_kmalloc_alignment __malloc;
343void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node) __assume_slab_alignment; 343void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node) __assume_slab_alignment __malloc;
344#else 344#else
345static __always_inline void *__kmalloc_node(size_t size, gfp_t flags, int node) 345static __always_inline void *__kmalloc_node(size_t size, gfp_t flags, int node)
346{ 346{
@@ -354,12 +354,12 @@ static __always_inline void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t f
354#endif 354#endif
355 355
356#ifdef CONFIG_TRACING 356#ifdef CONFIG_TRACING
357extern void *kmem_cache_alloc_trace(struct kmem_cache *, gfp_t, size_t) __assume_slab_alignment; 357extern void *kmem_cache_alloc_trace(struct kmem_cache *, gfp_t, size_t) __assume_slab_alignment __malloc;
358 358
359#ifdef CONFIG_NUMA 359#ifdef CONFIG_NUMA
360extern void *kmem_cache_alloc_node_trace(struct kmem_cache *s, 360extern void *kmem_cache_alloc_node_trace(struct kmem_cache *s,
361 gfp_t gfpflags, 361 gfp_t gfpflags,
362 int node, size_t size) __assume_slab_alignment; 362 int node, size_t size) __assume_slab_alignment __malloc;
363#else 363#else
364static __always_inline void * 364static __always_inline void *
365kmem_cache_alloc_node_trace(struct kmem_cache *s, 365kmem_cache_alloc_node_trace(struct kmem_cache *s,
@@ -392,10 +392,10 @@ kmem_cache_alloc_node_trace(struct kmem_cache *s,
392} 392}
393#endif /* CONFIG_TRACING */ 393#endif /* CONFIG_TRACING */
394 394
395extern void *kmalloc_order(size_t size, gfp_t flags, unsigned int order) __assume_page_alignment; 395extern void *kmalloc_order(size_t size, gfp_t flags, unsigned int order) __assume_page_alignment __malloc;
396 396
397#ifdef CONFIG_TRACING 397#ifdef CONFIG_TRACING
398extern void *kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order) __assume_page_alignment; 398extern void *kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order) __assume_page_alignment __malloc;
399#else 399#else
400static __always_inline void * 400static __always_inline void *
401kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order) 401kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order)
diff --git a/include/linux/string.h b/include/linux/string.h
index d3993a79a325..26b6f6a66f83 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -119,7 +119,7 @@ char *strreplace(char *s, char old, char new);
119 119
120extern void kfree_const(const void *x); 120extern void kfree_const(const void *x);
121 121
122extern char *kstrdup(const char *s, gfp_t gfp); 122extern char *kstrdup(const char *s, gfp_t gfp) __malloc;
123extern const char *kstrdup_const(const char *s, gfp_t gfp); 123extern const char *kstrdup_const(const char *s, gfp_t gfp);
124extern char *kstrndup(const char *s, size_t len, gfp_t gfp); 124extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
125extern void *kmemdup(const void *src, size_t len, gfp_t gfp); 125extern void *kmemdup(const void *src, size_t len, gfp_t gfp);