From: Oleksandr Tyshchenko <olekstysh@gmail.com>
To: xen-devel@lists.xenproject.org
Cc: sstabellini@kernel.org, Wei Liu <wl@xen.org>,
Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
George Dunlap <George.Dunlap@eu.citrix.com>,
Andrew Cooper <andrew.cooper3@citrix.com>,
Ian Jackson <ian.jackson@eu.citrix.com>, Tim Deegan <tim@xen.org>,
Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>,
julien.grall@arm.com, Paul Durrant <paul.durrant@citrix.com>,
Jan Beulich <jbeulich@suse.com>,
volodymyr_babchuk@epam.com
Subject: [Xen-devel] [PATCH V6 3/8] xen/common: Introduce _xrealloc function
Date: Thu, 26 Sep 2019 14:20:29 +0300 [thread overview]
Message-ID: <1569496834-7796-4-git-send-email-olekstysh@gmail.com> (raw)
In-Reply-To: <1569496834-7796-1-git-send-email-olekstysh@gmail.com>
From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
This patch introduces type-unsafe function which besides
re-allocation handles the following corner cases:
1. if requested size is zero, it will behave like xfree
2. if incoming pointer is not valid (NULL or ZERO_BLOCK_PTR),
it will behave like xmalloc
If both pointer and size are valid the function will re-allocate and
copy only if requested size and alignment don't fit in already
allocated space.
Subsequent patch will add type-safe helper macros.
Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.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>
CC: Paul Durrant <paul.durrant@citrix.com>
---
Changes V5 -> V6:
- change uint32_t to unsigned int for "pad" in add_padding()
- change back to _xmalloc
- move tmp_size declaration/calculation to the corresponding block
- use "!" over "== 0"
Changes V4 -> V5:
- avoid possible truncation with allocations of 4GiB or above
- introduce helper functions add(strip)_padding to avoid
duplicating the code
- omit the unnecessary casts, change u32 to uint32_t
when moving the code
- use _xzalloc instead of _xmalloc to get the tail
portion zeroed
- update pointer according to the requsted alignment
- compared against "size" instead of "tmp_size" for the allocations
above PAGE_SIZE
Changes V3 -> V4:
- add check for the alignment compatibility
- properly detect current size (take into the account a possible
fake alignment header)
- update comment in code/patch description
Changes RFC -> V3:
- behave like xmalloc if incoming pointer is ZERO_BLOCK_PTR or NULL
- return ZERO_BLOCK_PTR after xfree if requested size is zero
- add patch description
- use allocator internals to recognize current size of
the incoming pointer
- do not re-allocate and copy if requested size fits in already
allocated space
...
Original patch was initially posted by Sameer Goel:
https://lists.xen.org/archives/html/xen-devel/2017-06/msg00858.html
This could be considered as another attempt to add it:
https://www.mail-archive.com/kexec@lists.infradead.org/msg21335.html
[As it was previously discussed with Julien in IRC]
The reason for this patch to be an RFC is that patch itself is not
completely correct and I don't fully understand what/how should
be done for this patch to be accepted. Or whether community even
wants this to go in. So, to avoid bike shedding, the first target is
to collect feedback.
For everyone who wants more details why this is needed and
where used, please see next patch of this thread:
"iommu/arm: Add lightweight iommu_fwspec support"
In a nutshell, the upcoming "iommu_fwspec" support on ARM
is going to use xrealloc to expand an array for device IDs.
We really want to have "iommu_fwspec" support which will give us
a generic abstract way to add new device to the IOMMU based on
the generic IOMMU DT binding.
---
xen/common/xmalloc_tlsf.c | 114 ++++++++++++++++++++++++++++++++++++++--------
xen/include/xen/xmalloc.h | 1 +
2 files changed, 97 insertions(+), 18 deletions(-)
diff --git a/xen/common/xmalloc_tlsf.c b/xen/common/xmalloc_tlsf.c
index 1e8d72d..7ab2b3b 100644
--- a/xen/common/xmalloc_tlsf.c
+++ b/xen/common/xmalloc_tlsf.c
@@ -549,10 +549,40 @@ static void tlsf_init(void)
* xmalloc()
*/
+static void *strip_padding(void *p)
+{
+ struct bhdr *b = p - BHDR_OVERHEAD;
+
+ if ( b->size & FREE_BLOCK )
+ {
+ p -= b->size & ~FREE_BLOCK;
+ b = p - BHDR_OVERHEAD;
+ ASSERT(!(b->size & FREE_BLOCK));
+ }
+
+ return p;
+}
+
+static void *add_padding(void *p, unsigned long align)
+{
+ unsigned int pad;
+
+ if ( (pad = -(long)p & (align - 1)) != 0 )
+ {
+ void *q = p + pad;
+ struct bhdr *b = q - BHDR_OVERHEAD;
+
+ ASSERT(q > p);
+ b->size = pad | FREE_BLOCK;
+ p = q;
+ }
+
+ return p;
+}
+
void *_xmalloc(unsigned long size, unsigned long align)
{
void *p = NULL;
- u32 pad;
ASSERT(!in_irq());
@@ -573,14 +603,7 @@ void *_xmalloc(unsigned long size, unsigned long align)
return xmalloc_whole_pages(size - align + MEM_ALIGN, align);
/* Add alignment padding. */
- if ( (pad = -(long)p & (align - 1)) != 0 )
- {
- char *q = (char *)p + pad;
- struct bhdr *b = (struct bhdr *)(q - BHDR_OVERHEAD);
- ASSERT(q > (char *)p);
- b->size = pad | FREE_BLOCK;
- p = q;
- }
+ p = add_padding(p, align);
ASSERT(((unsigned long)p & (align - 1)) == 0);
return p;
@@ -593,10 +616,71 @@ void *_xzalloc(unsigned long size, unsigned long align)
return p ? memset(p, 0, size) : p;
}
-void xfree(void *p)
+void *_xrealloc(void *ptr, unsigned long size, unsigned long align)
{
- struct bhdr *b;
+ unsigned long curr_size;
+ void *p;
+
+ if ( !size )
+ {
+ xfree(ptr);
+ return ZERO_BLOCK_PTR;
+ }
+ if ( ptr == NULL || ptr == ZERO_BLOCK_PTR )
+ return _xmalloc(size, align);
+
+ ASSERT(!(align & (align - 1)));
+ if ( align < MEM_ALIGN )
+ align = MEM_ALIGN;
+
+ if ( !((unsigned long)ptr & (PAGE_SIZE - 1)) )
+ {
+ curr_size = (unsigned long)PFN_ORDER(virt_to_page(ptr)) << PAGE_SHIFT;
+
+ if ( size <= curr_size && !((unsigned long)ptr & (align - 1)) )
+ return ptr;
+ }
+ else
+ {
+ unsigned long tmp_size;
+ struct bhdr *b;
+
+ tmp_size = size + align - MEM_ALIGN;
+
+ if ( tmp_size < PAGE_SIZE )
+ tmp_size = (tmp_size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE :
+ ROUNDUP_SIZE(tmp_size);
+
+ /* Strip alignment padding. */
+ p = strip_padding(ptr);
+
+ b = p - BHDR_OVERHEAD;
+ curr_size = b->size & BLOCK_SIZE_MASK;
+
+ if ( tmp_size <= curr_size )
+ {
+ /* Add alignment padding. */
+ p = add_padding(p, align);
+
+ ASSERT(!((unsigned long)p & (align - 1)));
+
+ return p;
+ }
+ }
+
+ p = _xmalloc(size, align);
+ if ( p )
+ {
+ memcpy(p, ptr, min(curr_size, size));
+ xfree(ptr);
+ }
+
+ return p;
+}
+
+void xfree(void *p)
+{
if ( p == NULL || p == ZERO_BLOCK_PTR )
return;
@@ -621,13 +705,7 @@ void xfree(void *p)
}
/* Strip alignment padding. */
- b = (struct bhdr *)((char *)p - BHDR_OVERHEAD);
- if ( b->size & FREE_BLOCK )
- {
- p = (char *)p - (b->size & ~FREE_BLOCK);
- b = (struct bhdr *)((char *)p - BHDR_OVERHEAD);
- ASSERT(!(b->size & FREE_BLOCK));
- }
+ p = strip_padding(p);
xmem_pool_free(p, xenpool);
}
diff --git a/xen/include/xen/xmalloc.h b/xen/include/xen/xmalloc.h
index f075d2d..831152f 100644
--- a/xen/include/xen/xmalloc.h
+++ b/xen/include/xen/xmalloc.h
@@ -51,6 +51,7 @@ extern void xfree(void *);
/* Underlying functions */
extern void *_xmalloc(unsigned long size, unsigned long align);
extern void *_xzalloc(unsigned long size, unsigned long align);
+extern void *_xrealloc(void *ptr, unsigned long size, unsigned long align);
static inline void *_xmalloc_array(
unsigned long size, unsigned long align, unsigned long num)
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
next prev parent reply other threads:[~2019-09-26 11:21 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-09-26 11:20 [Xen-devel] [PATCH V6 0/8] iommu/arm: Add Renesas IPMMU-VMSA support + Linux's iommu_fwspec Oleksandr Tyshchenko
2019-09-26 11:20 ` [Xen-devel] [PATCH V6 1/8] iommu/arm: Add iommu_helpers.c file to keep common for IOMMUs stuff Oleksandr Tyshchenko
2019-09-26 11:20 ` [Xen-devel] [PATCH V6 2/8] iommu/arm: Add ability to handle deferred probing request Oleksandr Tyshchenko
2019-09-26 11:20 ` Oleksandr Tyshchenko [this message]
2019-09-26 12:19 ` [Xen-devel] [PATCH V6 3/8] xen/common: Introduce _xrealloc function Jan Beulich
2019-09-26 13:39 ` Oleksandr
2019-09-26 11:20 ` [Xen-devel] [PATCH V6 4/8] xen/common: Introduce xrealloc_flex_struct() helper macros Oleksandr Tyshchenko
2019-09-26 11:20 ` [Xen-devel] [PATCH V6 5/8] iommu/arm: Add lightweight iommu_fwspec support Oleksandr Tyshchenko
2019-09-26 11:20 ` [Xen-devel] [PATCH V6 6/8] iommu: Order the headers alphabetically in device_tree.c Oleksandr Tyshchenko
2019-09-26 11:20 ` [Xen-devel] [PATCH V6 7/8] iommu/arm: Introduce iommu_add_dt_device API Oleksandr Tyshchenko
2019-09-26 12:52 ` Julien Grall
2019-09-26 13:34 ` Oleksandr
2019-09-26 14:34 ` Jan Beulich
2019-09-26 11:20 ` [Xen-devel] [PATCH V6 8/8] iommu/arm: Add Renesas IPMMU-VMSA support Oleksandr Tyshchenko
2019-09-26 12:22 ` Jan Beulich
2019-09-26 13:32 ` Oleksandr
2019-09-26 14:56 ` [Xen-devel] [PATCH V6 0/8] iommu/arm: Add Renesas IPMMU-VMSA support + Linux's iommu_fwspec Julien Grall
2019-09-26 15:16 ` Oleksandr
2019-09-27 22:50 ` Stefano Stabellini
2019-09-27 23:52 ` Oleksandr Tyshchenko
2019-09-28 9:36 ` Julien Grall
2019-09-30 20:58 ` Stefano Stabellini
2019-10-01 9:23 ` Oleksandr
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1569496834-7796-4-git-send-email-olekstysh@gmail.com \
--to=olekstysh@gmail.com \
--cc=George.Dunlap@eu.citrix.com \
--cc=andrew.cooper3@citrix.com \
--cc=ian.jackson@eu.citrix.com \
--cc=jbeulich@suse.com \
--cc=julien.grall@arm.com \
--cc=konrad.wilk@oracle.com \
--cc=oleksandr_tyshchenko@epam.com \
--cc=paul.durrant@citrix.com \
--cc=sstabellini@kernel.org \
--cc=tim@xen.org \
--cc=volodymyr_babchuk@epam.com \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.