/* * EFFECT: * - split leaf&lmb into two leaves:a & b * a&b are both the half of the lmb * * PROCESS: * - leaf: * +-----------------------------------+ * | 0 | 1 | 2 | 3 | 4 | 5 | * +-----------------------------------+ * * - split: * root * +--------+ * | 2 | * +--------+ * / \ * +-----------------+ +------------------+ * | 0 | 1 | 2 | | 3 | 4 | 5 | * +-----------------+ +------------------+ * nodea nodeb * * ENTER: * - leaf is already locked (L_WRITE) * EXITS: * - a is locked * - b is locked */ void leaf_split(void *tree, struct node *node, struct node **a, struct node **b, struct msg **split_key) { struct partition *pa; struct partition *pb; struct node *leafa; struct node *leafb; struct lmb *mb; struct lmb *mba; struct lmb *mbb; struct msg *sp_key = NULL; struct buftree *t = (struct buftree*)tree; leafa = node; pa = &leafa->parts[0]; /* split lmb of leaf to mba & mbb */ mb = pa->msgbuf; lmb_split(mb, &mba, &mbb, &sp_key); lmb_free(mb); /* reset leafa buffer */ pa->msgbuf = mba; /* new leafb */ NID nid = hdr_next_nid(t->hdr); leaf_new(t->hdr, nid, 0, 1, &leafb); leaf_msgbuf_init(leafb); cache_put_and_pin(t->cf, nid, leafb); pb = &leafb->parts[0]; lmb_free(pb->msgbuf); pb->msgbuf = mbb; /* set dirty */ node_set_dirty(leafa); node_set_dirty(leafb); *a = leafa; *b = leafb; *split_key = sp_key; }
void node_free(struct node *node) { nassert(node != NULL); if (node->height == 0) { lmb_free(node->u.l.buffer); } else { uint32_t i; if (node->u.n.n_children > 0) { for (i = 0; i < node->u.n.n_children - 1; i++) { xfree(node->u.n.pivots[i].data); } for (i = 0; i < node->u.n.n_children; i++) { nmb_free(node->u.n.parts[i].buffer); } xfree(node->u.n.pivots); xfree(node->u.n.parts); } } xfree(node); }
void leaf_free(struct node *leaf) { int i; nassert(leaf != NULL); nassert(leaf->height == 0); for (i = 0; i < (leaf->n_children - 1); i++) xfree(leaf->pivots[i].data); for (i = 0; i < leaf->n_children; i++) lmb_free(leaf->parts[i].msgbuf); ness_mutex_destroy(&leaf->attr.mtx); xfree(leaf->pivots); xfree(leaf->parts); xfree(leaf); }
void __init free_unused_pacas(void) { int new_size; new_size = PAGE_ALIGN(sizeof(struct paca_struct) * num_possible_cpus()); if (new_size >= paca_size) return; lmb_free(__pa(paca) + new_size, paca_size - new_size); printk(KERN_DEBUG "Freed %u bytes for unused pacas\n", paca_size - new_size); paca_size = new_size; }
int image_setup_libfdt(bootm_headers_t *images, void *blob, int of_size, struct lmb *lmb) { ulong *initrd_start = &images->initrd_start; ulong *initrd_end = &images->initrd_end; int ret; if (fdt_chosen(blob, 1) < 0) { puts("ERROR: /chosen node create failed"); puts(" - must RESET the board to recover.\n"); return -1; } arch_fixup_memory_node(blob); if (IMAGE_OF_BOARD_SETUP) ft_board_setup(blob, gd->bd); fdt_fixup_ethernet(blob); /* Delete the old LMB reservation */ lmb_free(lmb, (phys_addr_t)(u32)(uintptr_t)blob, (phys_size_t)fdt_totalsize(blob)); ret = fdt_resize(blob); if (ret < 0) return ret; of_size = ret; if (*initrd_start && *initrd_end) { of_size += FDT_RAMDISK_OVERHEAD; fdt_set_totalsize(blob, of_size); } /* Create a new LMB reservation */ lmb_reserve(lmb, (ulong)blob, of_size); fdt_initrd(blob, *initrd_start, *initrd_end, 1); if (!ft_verify_fdt(blob)) return -1; return 0; }
int image_setup_libfdt(bootm_headers_t *images, void *blob, int of_size, struct lmb *lmb) { ulong *initrd_start = &images->initrd_start; ulong *initrd_end = &images->initrd_end; int ret = -EPERM; int fdt_ret; if (fdt_root(blob) < 0) { printf("ERROR: root node setup failed\n"); goto err; } if (fdt_chosen(blob) < 0) { printf("ERROR: /chosen node create failed\n"); goto err; } if (arch_fixup_fdt(blob) < 0) { printf("ERROR: arch-specific fdt fixup failed\n"); goto err; } if (IMAGE_OF_BOARD_SETUP) { fdt_ret = ft_board_setup(blob, gd->bd); if (fdt_ret) { printf("ERROR: board-specific fdt fixup failed: %s\n", fdt_strerror(fdt_ret)); goto err; } } if (IMAGE_OF_SYSTEM_SETUP) { fdt_ret = ft_system_setup(blob, gd->bd); if (fdt_ret) { printf("ERROR: system-specific fdt fixup failed: %s\n", fdt_strerror(fdt_ret)); goto err; } } fdt_fixup_ethernet(blob); /* Delete the old LMB reservation */ lmb_free(lmb, (phys_addr_t)(u32)(uintptr_t)blob, (phys_size_t)fdt_totalsize(blob)); ret = fdt_shrink_to_minimum(blob); if (ret < 0) goto err; of_size = ret; if (*initrd_start && *initrd_end) { of_size += FDT_RAMDISK_OVERHEAD; fdt_set_totalsize(blob, of_size); } /* Create a new LMB reservation */ lmb_reserve(lmb, (ulong)blob, of_size); fdt_initrd(blob, *initrd_start, *initrd_end); if (!ft_verify_fdt(blob)) goto err; #if defined(CONFIG_SOC_KEYSTONE) if (IMAGE_OF_BOARD_SETUP) ft_board_setup_ex(blob, gd->bd); #endif return 0; err: printf(" - must RESET the board to recover.\n\n"); return ret; }
/* * EFFECT: * - split leaf&lmb into two leaves:a & b * a&b are both the half of the lmb * * PROCESS: * - leaf: * +-----------------------------------+ * | 0 | 1 | 2 | 3 | 4 | 5 | * +-----------------------------------+ * * - split: * root * +--------+ * | 2 | * +--------+ * / \ * +-----------------+ +------------------+ * | 0 | 1 | 2 | | 3 | 4 | 5 | * +-----------------+ +------------------+ * nodea nodeb * * ENTER: * - leaf is already locked (L_WRITE) * EXITS: * - a is locked * - b is locked */ static void _leaf_and_lmb_split(struct tree *t, struct node *leaf, struct node **a, struct node **b, struct msg **split_key) { struct child_pointer *cptra; struct child_pointer *cptrb; struct node *leafa; struct node *leafb; struct lmb *mb; struct lmb *mba; struct lmb *mbb; struct msg *sp_key = NULL; __DEBUG("leaf split begin, NID %"PRIu64"" ", nodesz %d" ", nodec %d" ", children %d" , leaf->nid , node_size(leaf) , node_count(leaf) , leaf->n_children); leafa = leaf; cptra = &leafa->parts[0].ptr; /* split lmb of leaf to mba & mbb */ mb = cptra->u.leaf->buffer; lmb_split(mb, &mba, &mbb, &sp_key); lmb_free(mb); /* reset leafa buffer */ cptra->u.leaf->buffer = mba; /* new leafb */ NID nid = hdr_next_nid(t->hdr); node_create(nid, 0, 1, t->hdr->version, t->e, &leafb); cache_put_and_pin(t->cf, nid, leafb); cptrb = &leafb->parts[0].ptr; lmb_free(cptrb->u.leaf->buffer); cptrb->u.leaf->buffer = mbb; /* set dirty */ node_set_dirty(leafa); node_set_dirty(leafb); __DEBUG("leaf split end, leafa NID %"PRIu64"" ", nodesz %d" ", nodec %d" ", children %d" , leafa->nid , node_size(leafa) , node_count(leafa) , leafa->n_children); __DEBUG("leaf split end, leafb NID %"PRIu64"" ", nodesz %d" ", nodec %d" ", children %d" , leafb->nid , node_size(leafb) , node_count(leafb) , leafb->n_children); *a = leafa; *b = leafb; *split_key = sp_key; status_increment(&t->e->status->tree_leaf_split_nums); }
static void free_leaf(struct leaf_basement_node *leaf) { lmb_free(leaf->buffer); xfree(leaf); }