* Misunderstanding with function cpm_dpalloc in Linux 2.6.x
@ 2006-01-25 13:48 Laurent Lagrange
2006-01-25 16:14 ` Pantelis Antoniou
0 siblings, 1 reply; 7+ messages in thread
From: Laurent Lagrange @ 2006-01-25 13:48 UTC (permalink / raw)
To: linuxppc-embedded
Hello,
I work on MPC boards with Linux 2.6.9 and I have a problem with the
cpm_dpalloc function.
In the file cpm2_common.c the function "uint cpm_dpalloc(uint size, uint
align)" is intended
to allocate a piece of memory in the dpram. This piece of memory has at
least "size" bytes
and I beleived that the returned address should be aligned on "align" bytes.
This function calls "void *rh_alloc(rh_info_t * info, int size, const char
*owner)" from rheap.c file.
In this function the alignment is only used to calculate the right size with
the formula :
size = (size + (info->alignment - 1)) & ~(info->alignment - 1);
It seems to be right but the alignment is not used to retreive an aligned
start address.
So if I do the following sequential calls, I have the following results :
cpm_dpalloc(16, 8) -> 0XC0 -> right aligned
cpm_dpalloc(64, 64) -> 0XD0 -> wrong aligned -> must be 0x100
cpm_dpalloc(16, 8) -> 0X110 -> right aligned but wrong to use
cpm_dpalloc(24, 8) -> 0X1200 -> right aligned but wrong to use
I can have the wanted values if instead of size, I try to allocate (size +
align - 1) bytes
but I don't think it is the solution.
Perhaps, I don't understand the allocation theory.
Any idea ?
Thanks all
Laurent
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Misunderstanding with function cpm_dpalloc in Linux 2.6.x
2006-01-25 13:48 Misunderstanding with function cpm_dpalloc in Linux 2.6.x Laurent Lagrange
@ 2006-01-25 16:14 ` Pantelis Antoniou
2006-07-04 15:37 ` Linux 2.6.x : cpm_dpalloc alignment bug perhaps not fully resolved Laurent Lagrange
0 siblings, 1 reply; 7+ messages in thread
From: Pantelis Antoniou @ 2006-01-25 16:14 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 1507 bytes --]
On Wednesday 25 January 2006 15:48, Laurent Lagrange wrote:
>
> Hello,
>
> I work on MPC boards with Linux 2.6.9 and I have a problem with the
> cpm_dpalloc function.
>
> In the file cpm2_common.c the function "uint cpm_dpalloc(uint size, uint
> align)" is intended
> to allocate a piece of memory in the dpram. This piece of memory has at
> least "size" bytes
> and I beleived that the returned address should be aligned on "align" bytes.
>
> This function calls "void *rh_alloc(rh_info_t * info, int size, const char
> *owner)" from rheap.c file.
> In this function the alignment is only used to calculate the right size with
> the formula :
> size = (size + (info->alignment - 1)) & ~(info->alignment - 1);
> It seems to be right but the alignment is not used to retreive an aligned
> start address.
>
> So if I do the following sequential calls, I have the following results :
> cpm_dpalloc(16, 8) -> 0XC0 -> right aligned
> cpm_dpalloc(64, 64) -> 0XD0 -> wrong aligned -> must be 0x100
> cpm_dpalloc(16, 8) -> 0X110 -> right aligned but wrong to use
> cpm_dpalloc(24, 8) -> 0X1200 -> right aligned but wrong to use
>
> I can have the wanted values if instead of size, I try to allocate (size +
> align - 1) bytes
> but I don't think it is the solution.
>
> Perhaps, I don't understand the allocation theory.
> Any idea ?
>
> Thanks all
> Laurent
>
>
Laurent Hi,
Yes this is a know bug. This patch fixes it.
Marcelo, please apply - we have this hanging for quite a while.
Pantelis
[-- Attachment #2: cpm2-dpalloc.patch --]
[-- Type: text/x-diff, Size: 4160 bytes --]
diff --git a/arch/ppc/lib/rheap.c b/arch/ppc/lib/rheap.c
--- a/arch/ppc/lib/rheap.c
+++ b/arch/ppc/lib/rheap.c
@@ -425,17 +425,21 @@ void *rh_detach_region(rh_info_t * info,
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);
@@ -478,9 +482,21 @@ void *rh_alloc(rh_info_t * info, int siz
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)
{
diff --git a/arch/ppc/syslib/cpm2_common.c b/arch/ppc/syslib/cpm2_common.c
--- a/arch/ppc/syslib/cpm2_common.c
+++ b/arch/ppc/syslib/cpm2_common.c
@@ -148,8 +148,7 @@ uint cpm_dpalloc(uint size, uint align)
unsigned long flags;
spin_lock_irqsave(&cpm_dpmem_lock, flags);
- cpm_dpmem_info.alignment = align;
- start = rh_alloc(&cpm_dpmem_info, size, "commproc");
+ start = rh_alloc_align(&cpm_dpmem_info, size, align, "commproc");
spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
return (uint)start;
@@ -170,13 +169,12 @@ int cpm_dpfree(uint offset)
EXPORT_SYMBOL(cpm_dpfree);
/* not sure if this is ever needed */
-uint cpm_dpalloc_fixed(uint offset, uint size, uint align)
+uint cpm_dpalloc_fixed(uint offset, uint size)
{
void *start;
unsigned long flags;
spin_lock_irqsave(&cpm_dpmem_lock, flags);
- cpm_dpmem_info.alignment = align;
start = rh_alloc_fixed(&cpm_dpmem_info, (void *)offset, size, "commproc");
spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
diff --git a/include/asm-ppc/commproc.h b/include/asm-ppc/commproc.h
--- a/include/asm-ppc/commproc.h
+++ b/include/asm-ppc/commproc.h
@@ -74,7 +74,7 @@ static inline long IS_DPERR(const uint o
extern cpm8xx_t *cpmp; /* Pointer to comm processor */
extern uint cpm_dpalloc(uint size, uint align);
extern int cpm_dpfree(uint offset);
-extern uint cpm_dpalloc_fixed(uint offset, uint size, uint align);
+extern uint cpm_dpalloc_fixed(uint offset, uint size);
extern void cpm_dpdump(void);
extern void *cpm_dpram_addr(uint offset);
extern void cpm_setbrg(uint brg, uint rate);
diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h
--- a/include/asm-ppc/cpm2.h
+++ b/include/asm-ppc/cpm2.h
@@ -112,7 +112,7 @@ extern cpm_cpm2_t *cpmp; /* Pointer to
extern uint cpm_dpalloc(uint size, uint align);
extern int cpm_dpfree(uint offset);
-extern uint cpm_dpalloc_fixed(uint offset, uint size, uint align);
+extern uint cpm_dpalloc_fixed(uint offset, uint size);
extern void cpm_dpdump(void);
extern void *cpm_dpram_addr(uint offset);
extern void cpm_setbrg(uint brg, uint rate);
diff --git a/include/asm-ppc/rheap.h b/include/asm-ppc/rheap.h
--- a/include/asm-ppc/rheap.h
+++ b/include/asm-ppc/rheap.h
@@ -62,6 +62,10 @@ extern int rh_attach_region(rh_info_t *
/* 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);
^ permalink raw reply [flat|nested] 7+ messages in thread
* Linux 2.6.x : cpm_dpalloc alignment bug perhaps not fully resolved
2006-01-25 16:14 ` Pantelis Antoniou
@ 2006-07-04 15:37 ` Laurent Lagrange
0 siblings, 0 replies; 7+ messages in thread
From: Laurent Lagrange @ 2006-07-04 15:37 UTC (permalink / raw)
To: pantelis; +Cc: linuxppc-embedded
Hello Pantelis,
Few months ago (25 January 2006), I sent a mail about an alignment bug in
cpm_dpalloc.
I applied and verified the provided patch. I was very satisfied with the
result.
Today I port a driver from Linux 2.4 to Linux 2.6 and I have strange
results.
The driver allocates rx and tx bds (8 bytes aligned) in the module_init for
4 SCC ports.
That is always right. Then one port is opened by an application and a user
configuration
is set via an ioctl (set_conf).
This ioctl first frees the old bds :
cpm_dpfree(chan->rx_bd_offset);
cpm_dpfree(chan->tx_bd_offset);
then allocates the new ones :
chan->rx_bd_offset = cpm_dpalloc(sizeof(cbd_t) * chan->conf.rx_bufnbr, 8);
chan->tx_bd_offset = cpm_dpalloc(sizeof(cbd_t) * chan->conf.tx_bufnbr, 8);
with rx_bufnbr == 8 and tx_bufnbr == 2
module_init
SCC1 rx_bd_offset=160
SCC1 tx_bd_offset=1a8
SCC2 rx_bd_offset=1c0
SCC2 tx_bd_offset=208
SCC3 rx_bd_offset=220
SCC3 tx_bd_offset=260
SCC4 rx_bd_offset=278
SCC4 tx_bd_offset=2c0
set_conf
SCC1 rx_bd_offset=160
SCC1 tx_bd_offset=1a4 -> ???
module_init
SCC1 rx_bd_offset=160
SCC1 tx_bd_offset=1a8
SCC2 rx_bd_offset=1c0
SCC2 tx_bd_offset=208
SCC3 rx_bd_offset=220
SCC3 tx_bd_offset=260
SCC4 rx_bd_offset=278
SCC4 tx_bd_offset=2c0
set_conf
SCC2 rx_bd_offset=1c0
SCC2 tx_bd_offset=202 -> ???
module_init
SCC1 rx_bd_offset=160
SCC1 tx_bd_offset=1a8
SCC2 rx_bd_offset=1c0
SCC2 tx_bd_offset=208
SCC3 rx_bd_offset=220
SCC3 tx_bd_offset=260
SCC4 rx_bd_offset=278
SCC4 tx_bd_offset=2c0
set_conf
SCC3 rx_bd_offset=220
SCC3 tx_bd_offset=260 -> ok
module_init
SCC1 rx_bd_offset=160
SCC1 tx_bd_offset=1a8
SCC2 rx_bd_offset=1c0
SCC2 tx_bd_offset=208
SCC3 rx_bd_offset=220
SCC3 tx_bd_offset=260
SCC4 rx_bd_offset=278
SCC4 tx_bd_offset=2c0
set_conf
SCC4 rx_bd_offset=278
SCC4 tx_bd_offset=2c0 -> ok
WARNING : if I only uses the SCC1 port without allocating bds for the other
ports,
I can free and reallocate the bds for the SCC1 port as many times I want.
module_init
SCC1 rx_bd_offset=160
SCC1 tx_bd_offset=1a8
set_conf
SCC1 rx_bd_offset=160
SCC1 tx_bd_offset=1a8 -> ok
Really, I don't understand how this can arise.
Any idea ?
Thanks
Laurent
^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: Linux 2.6.x : cpm_dpalloc alignment bug perhaps not fully resolved
2006-07-05 2:32 Linux 2.6.x : cpm_dpalloc alignment bug perhaps not fully r esolved Li Yang-r58472
@ 2006-07-05 8:25 ` Laurent Lagrange
0 siblings, 0 replies; 7+ messages in thread
From: Laurent Lagrange @ 2006-07-05 8:25 UTC (permalink / raw)
To: 'Li Yang-r58472', pantelis; +Cc: linuxppc-embedded
Hi Leo,
Thanks for the reply.
The patch, I already applied, comes directly from Pantelis
and is the same code as found at
http://patchwork.ozlabs.org/linuxppc/patch?id=3484
What do you mean by the alignment patch ?
I suspect a problem in the cpm_dpfree function,
not in the cpm_dpalloc function.
I'll try to give more details.
Best regards
Laurent
> -----Message d'origine-----
> De : Li Yang-r58472 [mailto:LeoLi@freescale.com]
> Envoyé : mer. 5 juillet 2006 03:32
> À : Laurent Lagrange; pantelis@embeddedalley.com
> Cc : linuxppc-embedded@ozlabs.org
> Objet : RE: Linux 2.6.x : cpm_dpalloc alignment bug perhaps not fully
> resolved
>
>
> Did you apply the alignment patch too? AFAIK, the problem is
> never fixed in
> mainstream trees.
>
> Best Regards,
> Leo
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: Linux 2.6.x : cpm_dpalloc alignment bug perhaps not fully resolved
2006-07-05 8:35 Linux 2.6.x : cpm_dpalloc alignment bug perhaps not fully r esolved Li Yang-r58472
@ 2006-07-05 9:11 ` Laurent Lagrange
2006-07-05 9:38 ` Pantelis Antoniou
0 siblings, 1 reply; 7+ messages in thread
From: Laurent Lagrange @ 2006-07-05 9:11 UTC (permalink / raw)
To: 'Li Yang-r58472', pantelis; +Cc: linuxppc-embedded
> -----Message d'origine-----
> De : Li Yang-r58472 [mailto:LeoLi@freescale.com]
> Envoyé : mer. 5 juillet 2006 09:36
> À : Laurent Lagrange; pantelis@embeddedalley.com
> >
> > The patch, I already applied, comes directly from Pantelis
> > and is the same code as found at
> > http://patchwork.ozlabs.org/linuxppc/patch?id=3484
>
> Sure, it is the patch I mentioned. Also be noted that the
> patch only fixes rheap in arch/ppc/. If you are using latest
> 2.6 source, you are most probably using code under arch/powerpc/.
> >
I use a Linux 2.6.9 for MPC8260 and the arch/ppc/lib/rheap.c file.
I have no arch/powerpc tree in this kernel.
Before applying the patch, I was not able to get a right aligned area
with cpm_dpalloc. After applying it, cpm_dpalloc seems to be right
until I use cpm_dpfree and then cpm_dpalloc on the same area.
Another idea ?
Thanks
Laurent
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Linux 2.6.x : cpm_dpalloc alignment bug perhaps not fully resolved
2006-07-05 9:11 ` Linux 2.6.x : cpm_dpalloc alignment bug perhaps not fully resolved Laurent Lagrange
@ 2006-07-05 9:38 ` Pantelis Antoniou
2006-07-05 10:03 ` Laurent Lagrange
0 siblings, 1 reply; 7+ messages in thread
From: Pantelis Antoniou @ 2006-07-05 9:38 UTC (permalink / raw)
To: Laurent Lagrange; +Cc: linuxppc-embedded
On Wednesday 05 July 2006 12:11, Laurent Lagrange wrote:
>=20
> > -----Message d'origine-----
> > De : Li Yang-r58472 [mailto:LeoLi@freescale.com]
> > Envoy=E9 : mer. 5 juillet 2006 09:36
> > =C0 : Laurent Lagrange; pantelis@embeddedalley.com
> > >
> > > The patch, I already applied, comes directly from Pantelis
> > > and is the same code as found at
> > > http://patchwork.ozlabs.org/linuxppc/patch?id=3D3484
> >
> > Sure, it is the patch I mentioned. Also be noted that the
> > patch only fixes rheap in arch/ppc/. If you are using latest
> > 2.6 source, you are most probably using code under arch/powerpc/.
> > >
> I use a Linux 2.6.9 for MPC8260 and the arch/ppc/lib/rheap.c file.
> I have no arch/powerpc tree in this kernel.
>=20
> Before applying the patch, I was not able to get a right aligned area
> with cpm_dpalloc. After applying it, cpm_dpalloc seems to be right
> until I use cpm_dpfree and then cpm_dpalloc on the same area.
>=20
> Another idea ?
> Thanks
> Laurent
>=20
>=20
>=20
Should be a bug at the free. I'll take a look at it when I have a few
spare cycles.
Pantelis
^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: Linux 2.6.x : cpm_dpalloc alignment bug perhaps not fully resolved
2006-07-05 9:38 ` Pantelis Antoniou
@ 2006-07-05 10:03 ` Laurent Lagrange
0 siblings, 0 replies; 7+ messages in thread
From: Laurent Lagrange @ 2006-07-05 10:03 UTC (permalink / raw)
To: 'Pantelis Antoniou'; +Cc: linuxppc-embedded
> -----Message d'origine-----
> De : Pantelis Antoniou [mailto:pantelis@embeddedalley.com]
> Envoyé : mer. 5 juillet 2006 10:38
> À : Laurent Lagrange
> Cc : 'Li Yang-r58472'; linuxppc-embedded@ozlabs.org
> Objet : Re: Linux 2.6.x : cpm_dpalloc alignment bug perhaps not fully
> resolved
>
> Should be a bug at the free. I'll take a look at it when I have a few
> spare cycles.
>
> Pantelis
>
Yes, I think so.
I'll try to get more details if I can help you.
Best regards
Laurent
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2006-07-05 10:02 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-01-25 13:48 Misunderstanding with function cpm_dpalloc in Linux 2.6.x Laurent Lagrange
2006-01-25 16:14 ` Pantelis Antoniou
2006-07-04 15:37 ` Linux 2.6.x : cpm_dpalloc alignment bug perhaps not fully resolved Laurent Lagrange
-- strict thread matches above, loose matches on Subject: below --
2006-07-05 2:32 Linux 2.6.x : cpm_dpalloc alignment bug perhaps not fully r esolved Li Yang-r58472
2006-07-05 8:25 ` Linux 2.6.x : cpm_dpalloc alignment bug perhaps not fully resolved Laurent Lagrange
2006-07-05 8:35 Linux 2.6.x : cpm_dpalloc alignment bug perhaps not fully r esolved Li Yang-r58472
2006-07-05 9:11 ` Linux 2.6.x : cpm_dpalloc alignment bug perhaps not fully resolved Laurent Lagrange
2006-07-05 9:38 ` Pantelis Antoniou
2006-07-05 10:03 ` Laurent Lagrange
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).