diff mbox series

[1/3] xmalloc: stop using a magic '1' in alignment padding

Message ID 20190702163840.2107-2-paul.durrant@citrix.com (mailing list archive)
State Superseded
Headers show
Series xmalloc patches | expand

Commit Message

Paul Durrant July 2, 2019, 4:38 p.m. UTC
Alignment padding inserts a pseudo block header in front of the allocation,
sets its size field to the pad size and then ORs in 1, which is equivalent
to marking it as a free block, so that xfree() can distinguish it from a
real block header.

This patch simply replaces the magic '1' with the defined 'FREE_BLOCK' to
make it more obvious what's going on. Also, whilst in the neighbourhood,
it removes a stray space after a cast.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: George Dunlap <George.Dunlap@eu.citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Julien Grall <julien.grall@arm.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Wei Liu <wl@xen.org>
---
 xen/common/xmalloc_tlsf.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

Comments

Jan Beulich July 3, 2019, 9:38 a.m. UTC | #1
On 02.07.2019 18:38, Paul Durrant wrote:
> Alignment padding inserts a pseudo block header in front of the allocation,
> sets its size field to the pad size and then ORs in 1, which is equivalent
> to marking it as a free block, so that xfree() can distinguish it from a
> real block header.
> 
> This patch simply replaces the magic '1' with the defined 'FREE_BLOCK' to
> make it more obvious what's going on.

Hmm, that's still an abuse of some sort, I think. FREE_BLOCK
(together with USED_BLOCK, PREV_FREE, and PREV_USED) serve
block splitting and re-combination, which isn't strictly the
case here. But yes, I guess (ab)using the manifest constants is
still better than (ab)using the literal numbers.

> Also, whilst in the neighbourhood, it removes a stray space after a cast.

An option would have been to drop the cast altogether. The code
here appears to assume that void pointer arithmetic is not
allowed (as is indeed the case in plain C).

> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>
with one further adjustment:

> @@ -638,12 +638,12 @@ void xfree(void *p)
>       }
>   
>       /* Strip alignment padding. */
> -    b = (struct bhdr *)((char *) p - BHDR_OVERHEAD);
> -    if ( b->size & 1 )
> +    b = (struct bhdr *)((char *)p - BHDR_OVERHEAD);
> +    if ( b->size & FREE_BLOCK )
>       {
>           p = (char *)p - (b->size & ~1u);

This ~1u also wants to become ~FREE_BLOCK then. I guess the
change is easy enough to make while committing; I don't
expect the loss of the u suffix to actually cause any
problems. In fact its presence was not a problem only
because ->size can't get very large and is of u32 type.

Jan
Paul Durrant July 3, 2019, 9:44 a.m. UTC | #2
> -----Original Message-----
> From: Jan Beulich <JBeulich@suse.com>
> Sent: 03 July 2019 10:39
> To: Paul Durrant <Paul.Durrant@citrix.com>; xen-devel@lists.xenproject.org
> Cc: Julien Grall <julien.grall@arm.com>; Andrew Cooper <Andrew.Cooper3@citrix.com>; George Dunlap
> <George.Dunlap@citrix.com>; Ian Jackson <Ian.Jackson@citrix.com>; Stefano Stabellini
> <sstabellini@kernel.org>; Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>; Tim (Xen.org) <tim@xen.org>;
> Wei Liu <wl@xen.org>
> Subject: Re: [PATCH 1/3] xmalloc: stop using a magic '1' in alignment padding
> 
> On 02.07.2019 18:38, Paul Durrant wrote:
> > Alignment padding inserts a pseudo block header in front of the allocation,
> > sets its size field to the pad size and then ORs in 1, which is equivalent
> > to marking it as a free block, so that xfree() can distinguish it from a
> > real block header.
> >
> > This patch simply replaces the magic '1' with the defined 'FREE_BLOCK' to
> > make it more obvious what's going on.
> 
> Hmm, that's still an abuse of some sort, I think. FREE_BLOCK
> (together with USED_BLOCK, PREV_FREE, and PREV_USED) serve
> block splitting and re-combination, which isn't strictly the
> case here. But yes, I guess (ab)using the manifest constants is
> still better than (ab)using the literal numbers.
> 
> > Also, whilst in the neighbourhood, it removes a stray space after a cast.
> 
> An option would have been to drop the cast altogether. The code
> here appears to assume that void pointer arithmetic is not
> allowed (as is indeed the case in plain C).
> 

Yes, the code is pretty ancient. There's a whole bunch of cleanup/style adjustments (e.g. u32 -> uint32_t) too. I left this one for consistency.

> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> 
> Reviewed-by: Jan Beulich <jbeulich@suse.com>

Thanks.

> with one further adjustment:
> 
> > @@ -638,12 +638,12 @@ void xfree(void *p)
> >       }
> >
> >       /* Strip alignment padding. */
> > -    b = (struct bhdr *)((char *) p - BHDR_OVERHEAD);
> > -    if ( b->size & 1 )
> > +    b = (struct bhdr *)((char *)p - BHDR_OVERHEAD);
> > +    if ( b->size & FREE_BLOCK )
> >       {
> >           p = (char *)p - (b->size & ~1u);
> 
> This ~1u also wants to become ~FREE_BLOCK then.

Oh yes, sorry I missed that.

> I guess the
> change is easy enough to make while committing; I don't
> expect the loss of the u suffix to actually cause any
> problems. In fact its presence was not a problem only
> because ->size can't get very large and is of u32 type.
> 

Yes, please go ahead and fix on commit.

  Paul

> Jan
diff mbox series

Patch

diff --git a/xen/common/xmalloc_tlsf.c b/xen/common/xmalloc_tlsf.c
index 2076953ac4..6d889b7bdc 100644
--- a/xen/common/xmalloc_tlsf.c
+++ b/xen/common/xmalloc_tlsf.c
@@ -595,7 +595,7 @@  void *_xmalloc(unsigned long size, unsigned long align)
         char *q = (char *)p + pad;
         struct bhdr *b = (struct bhdr *)(q - BHDR_OVERHEAD);
         ASSERT(q > (char *)p);
-        b->size = pad | 1;
+        b->size = pad | FREE_BLOCK;
         p = q;
     }
 
@@ -638,12 +638,12 @@  void xfree(void *p)
     }
 
     /* Strip alignment padding. */
-    b = (struct bhdr *)((char *) p - BHDR_OVERHEAD);
-    if ( b->size & 1 )
+    b = (struct bhdr *)((char *)p - BHDR_OVERHEAD);
+    if ( b->size & FREE_BLOCK )
     {
         p = (char *)p - (b->size & ~1u);
         b = (struct bhdr *)((char *)p - BHDR_OVERHEAD);
-        ASSERT(!(b->size & 1));
+        ASSERT(!(b->size & FREE_BLOCK));
     }
 
     xmem_pool_free(p, xenpool);