xen/common: Use enhanced ASSERT_ALLOC_CONTEXT in xmalloc()
authorHenry Wang <Henry.Wang@arm.com>
Sat, 7 May 2022 02:54:34 +0000 (10:54 +0800)
committerJulien Grall <jgrall@amazon.com>
Wed, 8 Jun 2022 09:40:08 +0000 (10:40 +0100)
xmalloc() will use a pool for allocation smaller than a page.
The pool is extended only when there are no more space. At which
point, alloc_xenheap_pages() is called to add more memory.

xmalloc() must be protected by ASSERT_ALLOC_CONTEXT. It should not
rely on pool expanding to trigger the ASSERT_ALLOC_CONTEXT in
alloc_xenheap_pages(). Hence, this commit moves the definition of
ASSERT_ALLOC_CONTEXT to header and uses the ASSERT_ALLOC_CONTEXT
to replace the original assertion in xmalloc().

For consistency, the same assertion should be used in xfree(),
and the position of the assertion should be at the beginning of
the xfree().

Also take the opportunity to enhance the non-static functions
xmem_pool_{alloc,free}() with the same assertion so that future
callers of these two functions can be benefited.

Reported-by: Wei Chen <Wei.Chen@arm.com>
Suggested-by: Julien Grall <jgrall@amazon.com>
Signed-off-by: Henry Wang <Henry.Wang@arm.com>
Tested-by: Julien Grall <jgrall@amazon.com>
Acked-by: Julien Grall <jgrall@amazon.com>
xen/common/page_alloc.c
xen/common/xmalloc_tlsf.c
xen/include/xen/irq.h

index e866e0d864698eb9e07387177f3abf07ef5ccb66..ea59cd1a4aba24f6c55c4ec2e1f2f1540e74ab06 100644 (file)
 static char __initdata opt_badpage[100] = "";
 string_param("badpage", opt_badpage);
 
-/*
- * Heap allocations may need TLB flushes which may require IRQs to be
- * enabled (except when only 1 PCPU is online).
- */
-#define ASSERT_ALLOC_CONTEXT() \
-    ASSERT(!in_irq() && (local_irq_is_enabled() || num_online_cpus() <= 1))
-
 /*
  * no-bootscrub -> Free pages are not zeroed during boot.
  */
index d2ad909502d0528f19692b57d15ec727ad7df2a0..75bdf18c4ea7d4ea96a5eb51699a0354b7db166c 100644 (file)
@@ -378,6 +378,8 @@ void *xmem_pool_alloc(unsigned long size, struct xmem_pool *pool)
     int fl, sl;
     unsigned long tmp_size;
 
+    ASSERT_ALLOC_CONTEXT();
+
     if ( size < MIN_BLOCK_SIZE )
         size = MIN_BLOCK_SIZE;
     else
@@ -456,6 +458,8 @@ void xmem_pool_free(void *ptr, struct xmem_pool *pool)
     struct bhdr *b, *tmp_b;
     int fl = 0, sl = 0;
 
+    ASSERT_ALLOC_CONTEXT();
+
     if ( unlikely(ptr == NULL) )
         return;
 
@@ -594,7 +598,7 @@ void *_xmalloc(unsigned long size, unsigned long align)
 {
     void *p = NULL;
 
-    ASSERT(!in_irq());
+    ASSERT_ALLOC_CONTEXT();
 
     if ( !size )
         return ZERO_BLOCK_PTR;
@@ -697,11 +701,11 @@ void *_xrealloc(void *ptr, unsigned long size, unsigned long align)
 
 void xfree(void *p)
 {
+    ASSERT_ALLOC_CONTEXT();
+
     if ( p == NULL || p == ZERO_BLOCK_PTR )
         return;
 
-    ASSERT(!in_irq());
-
     if ( !((unsigned long)p & (PAGE_SIZE - 1)) )
     {
         unsigned long size = PFN_ORDER(virt_to_page(p));
index d8beadd16b9f7261b6cf82203b42ac1ced7ae7bf..300625e56db29716d1d608829f045db475df53f7 100644 (file)
 #include <asm/hardirq.h>
 #include <public/event_channel.h>
 
+/*
+ * Heap allocations may need TLB flushes which may require IRQs to be
+ * enabled (except when only 1 PCPU is online).
+ */
+#define ASSERT_ALLOC_CONTEXT() \
+    ASSERT(!in_irq() && (local_irq_is_enabled() || num_online_cpus() <= 1))
+
 struct irqaction {
     void (*handler)(int, void *, struct cpu_user_regs *);
     const char *name;