aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2006-11-30 22:01:43 -0500
committerPaul Mundt <lethal@linux-sh.org>2006-12-05 20:45:39 -0500
commit9f650cf2b811cfb605f10483eeb1dc86f43cdbcb (patch)
treedb9506994a49ecdd9151776fe5fb3ed7f3343c92
parent6fc21b82ef74911887ced1aff8d37ce079bb8b36 (diff)
sh: Fix store queue bitmap end.
The end of the store queue bitmap is miscalculated when searching for a free range in sq_remap(), missing the PAGE_SHIFT shift that's done in sq_api_init(). This runs in to workloads where we can scan beyond the end of the bitmap. Spotted by Paul Jackson: http://marc.theaimsgroup.com/?l=linux-kernel&m=116493191224097&w Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--arch/sh/kernel/cpu/sh4/sq.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c
index 7bcc73f9b8df..55f43506995a 100644
--- a/arch/sh/kernel/cpu/sh4/sq.c
+++ b/arch/sh/kernel/cpu/sh4/sq.c
@@ -19,7 +19,7 @@
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/vmalloc.h> 20#include <linux/vmalloc.h>
21#include <linux/mm.h> 21#include <linux/mm.h>
22#include <asm/io.h> 22#include <linux/io.h>
23#include <asm/page.h> 23#include <asm/page.h>
24#include <asm/cacheflush.h> 24#include <asm/cacheflush.h>
25#include <asm/cpu/sq.h> 25#include <asm/cpu/sq.h>
@@ -67,6 +67,7 @@ void sq_flush_range(unsigned long start, unsigned int len)
67 /* Wait for completion */ 67 /* Wait for completion */
68 store_queue_barrier(); 68 store_queue_barrier();
69} 69}
70EXPORT_SYMBOL(sq_flush_range);
70 71
71static inline void sq_mapping_list_add(struct sq_mapping *map) 72static inline void sq_mapping_list_add(struct sq_mapping *map)
72{ 73{
@@ -166,7 +167,7 @@ unsigned long sq_remap(unsigned long phys, unsigned int size,
166 map->size = size; 167 map->size = size;
167 map->name = name; 168 map->name = name;
168 169
169 page = bitmap_find_free_region(sq_bitmap, 0x04000000, 170 page = bitmap_find_free_region(sq_bitmap, 0x04000000 >> PAGE_SHIFT,
170 get_order(map->size)); 171 get_order(map->size));
171 if (unlikely(page < 0)) { 172 if (unlikely(page < 0)) {
172 ret = -ENOSPC; 173 ret = -ENOSPC;
@@ -193,6 +194,7 @@ out:
193 kmem_cache_free(sq_cache, map); 194 kmem_cache_free(sq_cache, map);
194 return ret; 195 return ret;
195} 196}
197EXPORT_SYMBOL(sq_remap);
196 198
197/** 199/**
198 * sq_unmap - Unmap a Store Queue allocation 200 * sq_unmap - Unmap a Store Queue allocation
@@ -234,6 +236,7 @@ void sq_unmap(unsigned long vaddr)
234 236
235 kmem_cache_free(sq_cache, map); 237 kmem_cache_free(sq_cache, map);
236} 238}
239EXPORT_SYMBOL(sq_unmap);
237 240
238/* 241/*
239 * Needlessly complex sysfs interface. Unfortunately it doesn't seem like 242 * Needlessly complex sysfs interface. Unfortunately it doesn't seem like
@@ -402,7 +405,3 @@ module_exit(sq_api_exit);
402MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, M. R. Brown <mrbrown@0xd6.org>"); 405MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, M. R. Brown <mrbrown@0xd6.org>");
403MODULE_DESCRIPTION("Simple API for SH-4 integrated Store Queues"); 406MODULE_DESCRIPTION("Simple API for SH-4 integrated Store Queues");
404MODULE_LICENSE("GPL"); 407MODULE_LICENSE("GPL");
405
406EXPORT_SYMBOL(sq_remap);
407EXPORT_SYMBOL(sq_unmap);
408EXPORT_SYMBOL(sq_flush_range);