diff options
author | Christoph Lameter <cl@linux.com> | 2011-05-16 16:26:08 -0400 |
---|---|---|
committer | Pekka Enberg <penberg@kernel.org> | 2011-05-17 15:18:55 -0400 |
commit | 1393d9a1857471f816d0be1ccc1d6433a86050f6 (patch) | |
tree | 2bcad46d15f1dc7ea6e458f2ab4d7f17b766dd66 /mm | |
parent | 6332aa9d25e911cc97aa9cc09acee21afda07ea6 (diff) |
slub: Make CONFIG_DEBUG_PAGE_ALLOC work with new fastpath
Fastpath can do a speculative access to a page that CONFIG_DEBUG_PAGE_ALLOC may have
marked as invalid to retrieve the pointer to the next free object.
Use probe_kernel_read in that case in order not to cause a page fault.
Cc: <stable@kernel.org> # 38.x
Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/slub.c | 14 |
1 files changed, 13 insertions, 1 deletions
@@ -261,6 +261,18 @@ static inline void *get_freepointer(struct kmem_cache *s, void *object) | |||
261 | return *(void **)(object + s->offset); | 261 | return *(void **)(object + s->offset); |
262 | } | 262 | } |
263 | 263 | ||
264 | static inline void *get_freepointer_safe(struct kmem_cache *s, void *object) | ||
265 | { | ||
266 | void *p; | ||
267 | |||
268 | #ifdef CONFIG_DEBUG_PAGEALLOC | ||
269 | probe_kernel_read(&p, (void **)(object + s->offset), sizeof(p)); | ||
270 | #else | ||
271 | p = get_freepointer(s, object); | ||
272 | #endif | ||
273 | return p; | ||
274 | } | ||
275 | |||
264 | static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp) | 276 | static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp) |
265 | { | 277 | { |
266 | *(void **)(object + s->offset) = fp; | 278 | *(void **)(object + s->offset) = fp; |
@@ -1933,7 +1945,7 @@ redo: | |||
1933 | if (unlikely(!this_cpu_cmpxchg_double( | 1945 | if (unlikely(!this_cpu_cmpxchg_double( |
1934 | s->cpu_slab->freelist, s->cpu_slab->tid, | 1946 | s->cpu_slab->freelist, s->cpu_slab->tid, |
1935 | object, tid, | 1947 | object, tid, |
1936 | get_freepointer(s, object), next_tid(tid)))) { | 1948 | get_freepointer_safe(s, object), next_tid(tid)))) { |
1937 | 1949 | ||
1938 | note_cmpxchg_failure("slab_alloc", s, tid); | 1950 | note_cmpxchg_failure("slab_alloc", s, tid); |
1939 | goto redo; | 1951 | goto redo; |