Commit be7b3caa authored by Charlie Jacobsen's avatar Charlie Jacobsen Committed by Vikram Narayanan

libcap-integration: Resource trees partially integrated into kliblcd.

Enter/exit code sets up/tears down the thread's tree.

Fixed a few spotted bugs in allocation and tree code.
parent e54b8ec7
......@@ -17,7 +17,9 @@
/* For LCDs */
#define INIT_LCD(tsk) \
.lcd = NULL, .cptr_cache = NULL,
.lcd = NULL, \
.cptr_cache = NULL, \
.lcd_resource_trees[0] = NULL, .lcd_resource_trees[1] = NULL,
#ifdef CONFIG_SMP
# define INIT_PUSHABLE_TASKS(tsk) \
......
......@@ -63,6 +63,7 @@ struct sched_param {
/* For LCDs */
struct lcd;
struct cptr_cache;
struct lcd_resource_tree;
#include <asm/processor.h>
......@@ -1928,6 +1929,7 @@ struct task_struct {
#endif
struct lcd *lcd;
struct cptr_cache *cptr_cache;
struct lcd_resource_tree *lcd_resource_trees[2];
/* CPU-specific state of this task */
struct thread_struct thread;
......
......@@ -70,10 +70,14 @@ lcd_resource_tree_first(struct lcd_resource_tree *t)
struct lcd_resource_node *
lcd_resource_tree_next(struct lcd_resource_node *n)
{
return container_of(
container_of(rb_next(n), struct interval_tree_node, rb),
struct lcd_resource_node,
it_node);
struct rb_node *rb_node = rb_next(&n->it_node.rb);
if (rb_node) {
return container_of(
container_of(rb_node, struct interval_tree_node, rb),
struct lcd_resource_node,
it_node);
} else
return NULL;
}
void lcd_resource_tree_remove(struct lcd_resource_tree *t,
......
......@@ -40,11 +40,20 @@ struct lcd_resource_tree {
*
* You are responsible for allocating these things and freeing
* them when you're done with them.
*
* You can use flags in any way you wish. Some common flags are
* defined below.
*/
struct lcd_resource_node {
struct interval_tree_node it_node;
unsigned long nr_pages_order;
cptr_t cptr;
unsigned int flags;
};
enum {
LCD_RESOURCE_NODE_STATIC = 0, /* resource node statically alloc'd */
LCD_RESOURCE_NODE_KMALLOC = 1, /* resource node alloc'd via kmallc */
};
static inline unsigned long
......@@ -71,6 +80,12 @@ lcd_resource_node_cptr(struct lcd_resource_node *n)
return n->cptr;
}
static inline unsigned int
lcd_resource_node_flags(struct lcd_resource_node *n)
{
return n->flags;
}
/* INTERFACE -------------------------------------------------- */
/**
......
......@@ -13,6 +13,7 @@ int lcd_enter(void)
int ret;
struct lcd *lcd;
struct cptr_cache *cache;
struct lcd_resource_tree *t;
cptr_t unused;
/*
* This sets up the runtime environment for non-isolated
......@@ -70,9 +71,28 @@ int lcd_enter(void)
LCD_ERR("creating call endpoint");
goto fail6;
}
/*
* Set up resource trees
*/
ret = lcd_alloc_init_resource_tree(&t);
if (ret) {
LCD_ERR("creating resource tree");
goto fail7;
}
current->lcd_resource_trees[0] = t;
ret = lcd_alloc_init_resource_tree(&t);
if (ret) {
LCD_ERR("creating resource tree");
goto fail8;
}
current->lcd_resource_trees[1] = t;
return 0;
fail8:
fail7:
fail6:
fail5:
fail4:
fail3:
fail2:
......@@ -112,8 +132,14 @@ void lcd_exit(int retval)
do_destroy_lcd(current->lcd);
if (current->cptr_cache)
do_destroy_cptr_cache(current->cptr_cache);
if (current->lcd_resource_trees[0])
lcd_destroy_free_resource_tree(current->lcd_resource_trees[0]);
if (current->lcd_resource_trees[1])
lcd_destroy_free_resource_tree(current->lcd_resource_trees[1]);
current->lcd = NULL;
current->cptr_cache = NULL;
current->lcd_resource_trees[0] = NULL;
current->lcd_resource_trees[1] = NULL;
/* (Call endpoint should be auto-destroyed when we destroy
* the LCD because this will destroy its cspace. So long as
* the LCD didn't grant the endpoint to someone.) */
......
......@@ -8,6 +8,72 @@
#include <lcd-domains/liblcd.h>
#include "../microkernel/internal.h"
/* RESOURCE TREES -------------------------------------------------- */
/* There are two trees: One for RAM and device memory (host physical
* addresses), one for vmalloc (host virtual addresses for memory that
* need not be contiguous). */
#define LCD_RESOURCE_TREE_RAM_IDX 0
#define LCD_RESOURCE_TREE_DEV_MEM_IDX 0
#define LCD_RESOURCE_TREE_VMALLOC_IDX 1
int lcd_alloc_init_resource_tree(struct lcd_resource_tree **t_out)
{
int ret;
struct lcd_resource_tree *t;
/*
* Create an empty resource tree for address -> cptr
* translation.
*/
t = kzalloc(sizeof(struct lcd_resource_tree),
GFP_KERNEL);
if (!t){
LCD_ERR("alloc'ing resource tree");
ret = -ENOMEM;
goto fail1;
}
/*
* Initialize it
*/
ret = lcd_resource_tree_init(t);
if (ret) {
LCD_ERR("error initializing resource tree");
goto fail2;
}
*t_out = t;
return 0;
fail2:
kfree(t);
fail1:
return ret;
}
void lcd_destroy_free_resource_tree(struct lcd_resource_tree *t)
{
struct lcd_resource_node *n, *next;
/*
* Destroy all of the nodes that are still lying around in the
* tree.
*/
n = lcd_resource_tree_first(t);
while (n) {
/*
* If this node was kmalloc'd, kfree it.
*/
next = lcd_resource_tree_next(n);
if (lcd_resource_node_flags(n) & LCD_RESOURCE_NODE_KMALLOC)
kfree(n);
n = next;
}
/*
* Free the root (for kliblcd, this is always kmalloc'd)
*/
kfree(t);
}
/* LOW-LEVEL PAGE ALLOC -------------------------------------------------- */
int _lcd_alloc_pages_exact_node(int nid, unsigned int flags,
......@@ -135,7 +201,7 @@ struct page *lcd_alloc_pages(unsigned int flags, unsigned int order)
/*
* Do lower-level alloc so that pages go into caller's cspace
*/
ret = _lcd_alloc_pages_node(flags, order, &slot);
ret = _lcd_alloc_pages(flags, order, &slot);
if (ret) {
LIBLCD_ERR("lower level alloc failed");
goto fail1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment