mp = palacios_alloc_extended(sizeof(struct buddy_mempool), GFP_KERNEL, zone->node_id);
- if (IS_ERR(mp)) {
+ if (!mp) {
ERROR("Could not allocate mempool\n");
return -1;
}
BITS_TO_LONGS(mp->num_blocks) * sizeof(long), GFP_KERNEL, zone->node_id
);
+ if (!(mp->tag_bits)) {
+ ERROR("Could not allocate tag_bits\n");
+ palacios_free(mp);
+ return -1;
+ }
+
+
/* Initially mark all minimum-sized blocks as allocated */
bitmap_zero(mp->tag_bits, mp->num_blocks);
*user_metadata = pool->user_metadata;
- list_del(&(block->link));
+ if (is_available(pool,block)) {
+ list_del(&(block->link));
+ } else {
+ // we may not be on the free list if we are being
+ // forcibly removed before all allocations are freed
+ }
+
rb_erase(&(pool->tree_node), &(zone->mempools));
palacios_free(pool->tag_bits);
unsigned long flags = 0;
int ret = 0;
+
palacios_spinlock_lock_irqsave(&(zone->lock), flags);
ret = __buddy_remove_mempool(zone, base_addr, force, user_metadata);
palacios_spinlock_unlock_irqrestore(&(zone->lock), flags);
/**
* Returns a block of memory to the buddy system memory allocator.
*/
-void
+int
buddy_free(
//! Buddy system memory allocator object.
struct buddy_memzone * zone,
pool = find_mempool(zone, addr);
if ((pool == NULL) || (order > pool->pool_order)) {
- WARNING("Attempted to free an invalid page address (%p)\n", (void *)addr);
+ WARNING("Attempted to free an invalid page address (%p) - pool=%p order=%lu\n", (void *)addr,pool,order);
palacios_spinlock_unlock_irqrestore(&(zone->lock), flags);
- return;
+ return -1;
}
if (is_available(pool, block)) {
ERROR("Error: Freeing an available block\n");
palacios_spinlock_unlock_irqrestore(&(zone->lock), flags);
- return;
+ return -1;
}
pool->num_free_blocks += (1UL << (order - zone->min_order));
list_add(&(block->link), &(zone->avail[order]));
palacios_spinlock_unlock_irqrestore(&(zone->lock), flags);
+
+ return 0;
}