[POWERPC] Fix rheap alignment problem
authorLi Yang <leoli@freescale.com>
Fri, 29 Sep 2006 10:15:52 +0000 (18:15 +0800)
committerPaul Mackerras <paulus@samba.org>
Mon, 2 Oct 2006 10:27:47 +0000 (20:27 +1000)
Honor alignment parameter in the rheap allocator.  This is needed by
qe_lib.
Remove compile warning.

Signed-off-by: Pantelis Antoniou <pantelis@embeddedalley.com>
Signed-off-by: Li Yang <leoli@freescale.com>
Acked-by: Kumar Galak <galak@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
arch/powerpc/lib/Makefile
arch/powerpc/lib/rheap.c
include/asm-ppc/rheap.h

index 8030f6245d820795505806cdd6f8e76e872b0dbb..a0360ae10d0ccd5db00a1a0ff77b6bde74bd1629 100644 (file)
@@ -14,6 +14,7 @@ endif
 obj-$(CONFIG_PPC64)    += checksum_64.o copypage_64.o copyuser_64.o \
                           memcpy_64.o usercopy_64.o mem_64.o string.o \
                           strcase.o
+obj-$(CONFIG_QUICC_ENGINE) += rheap.o
 obj-$(CONFIG_XMON)     += sstep.o
 
 ifeq ($(CONFIG_PPC64),y)
index 31e511856dc58bc2b819e80c32a35840db5bd9ca..57bf991ccd6e11751cf4b37c5f4548ac83e55aba 100644 (file)
@@ -423,17 +423,21 @@ void *rh_detach_region(rh_info_t * info, void *start, int size)
        return (void *)s;
 }
 
-void *rh_alloc(rh_info_t * info, int size, const char *owner)
+void *rh_alloc_align(rh_info_t * info, int size, int alignment, const char *owner)
 {
        struct list_head *l;
        rh_block_t *blk;
        rh_block_t *newblk;
        void *start;
 
-       /* Validate size */
-       if (size <= 0)
+       /* Validate size, (must be power of two) */
+       if (size <= 0 || (alignment & (alignment - 1)) != 0)
                return ERR_PTR(-EINVAL);
 
+       /* given alignment larger that default rheap alignment */
+       if (alignment > info->alignment)
+               size += alignment - 1;
+
        /* Align to configured alignment */
        size = (size + (info->alignment - 1)) & ~(info->alignment - 1);
 
@@ -476,15 +480,27 @@ void *rh_alloc(rh_info_t * info, int size, const char *owner)
 
        attach_taken_block(info, newblk);
 
+       /* for larger alignment return fixed up pointer  */
+       /* this is no problem with the deallocator since */
+       /* we scan for pointers that lie in the blocks   */
+       if (alignment > info->alignment)
+               start = (void *)(((unsigned long)start + alignment - 1) &
+                               ~(alignment - 1));
+
        return start;
 }
 
+void *rh_alloc(rh_info_t * info, int size, const char *owner)
+{
+       return rh_alloc_align(info, size, info->alignment, owner);
+}
+
 /* allocate at precisely the given address */
 void *rh_alloc_fixed(rh_info_t * info, void *start, int size, const char *owner)
 {
        struct list_head *l;
        rh_block_t *blk, *newblk1, *newblk2;
-       unsigned long s, e, m, bs, be;
+       unsigned long s, e, m, bs = 0, be = 0;
 
        /* Validate size */
        if (size <= 0)
index e6ca1f67cedc0e526ad36d9dba1c784d88db7ad2..65b93225a7786016845e2a4db544571c743445af 100644 (file)
@@ -62,6 +62,10 @@ extern int rh_attach_region(rh_info_t * info, void *start, int size);
 /* Detach a free region */
 extern void *rh_detach_region(rh_info_t * info, void *start, int size);
 
+/* Allocate the given size from the remote heap (with alignment) */
+extern void *rh_alloc_align(rh_info_t * info, int size, int alignment,
+               const char *owner);
+
 /* Allocate the given size from the remote heap */
 extern void *rh_alloc(rh_info_t * info, int size, const char *owner);