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

PMFS isolation: full init operational (minus function pointers).

bdi init/destroy in place. Fixed some data store bugs.

file system type function pointers not set up yet. Need to figure out
strategy for handling them (during mount).
parent 9e842950
......@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <asm/page.h>
#include <linux/bug.h>
/* CPTRs -------------------------------------------------- */
......@@ -98,6 +99,50 @@ static inline unsigned long lcd_cptr_level(cptr_t c)
return i;
}
static inline cptr_t lcd_cptr_set_slot(cptr_t c, unsigned slot)
{
BUG_ON(slot >= (1 << LCD_CPTR_SLOT_BITS));
return __cptr(cptr_val(c) | slot);
}
static inline cptr_t lcd_cptr_set_fanout(cptr_t c, unsigned fanout_idx,
int lvl)
{
BUG_ON(lvl >= (1 << LCD_CPTR_DEPTH_BITS));
BUG_ON(fanout_idx >= (1 << LCD_CPTR_FANOUT_BITS));
return __cptr(cptr_val(c) |
(fanout_idx << (LCD_CPTR_SLOT_BITS +
lvl * LCD_CPTR_FANOUT_BITS)));
}
static inline cptr_t lcd_cptr_set_lvl(cptr_t c, int lvl)
{
BUG_ON(lvl >= (1 << LCD_CPTR_DEPTH_BITS));
return __cptr(cptr_val(c) | (lvl << LCD_CPTR_LEVEL_SHIFT));
}
static inline cptr_t mk_cptr(unsigned long lvl,
unsigned long fanouts[(1 << LCD_CPTR_DEPTH_BITS) - 1],
unsigned long slot)
{
unsigned long result = 0;
int i;
result |= lvl << LCD_CPTR_LEVEL_SHIFT;
for (i = 0; i < lvl; i++) {
result |=
(fanouts[i] <<
(lvl * LCD_CPTR_FANOUT_BITS +
LCD_CPTR_SLOT_BITS));
}
result |= slot;
return __cptr(result);
}
/* CPTR CACHE -------------------------------------------------- */
struct cptr_cache {
......
......@@ -338,6 +338,12 @@ static void lcd_free_dptr(struct dptr_cache *dptr_cache, dptr_t d)
/* DATA STORE -------------------------------------------------- */
/*
* This is used in a hack to make the cnode table slab caches
* work. See init cspace routine.
*/
static u64 dstore_id = 0;
static int make_empty_dstore_node_table(struct dstore *dstore,
uint8_t level,
struct dstore_node_table **new_out)
......@@ -385,6 +391,7 @@ int lcd_dstore_init_dstore(struct dstore **out)
{
int ret;
struct dstore *dstore;
char name[32];
/*
* Alloc
......@@ -410,9 +417,20 @@ int lcd_dstore_init_dstore(struct dstore **out)
INIT_LIST_HEAD(&dstore->table_list);
/*
* Initialize the dstore node table cache
* Initialize the dstore node table cache. We can't use the
* KMEM_CACHE macro because we need to use unique names. This
* is kind of hacky right now. (If you don't use a unique name,
* you might get an error/crash when you destroy the kmem cache
* for multiple lcd's. This is because slabs are tied to sysfs, and
* it complains when it tries to remove slabs with the same name.)
*/
dstore->dstore_node_table_cache = KMEM_CACHE(dstore_node_table, 0);
snprintf(name, 32, "dstore%llu", dstore_id);
dstore->dstore_node_table_cache = kmem_cache_create(
name,
sizeof(struct dstore_node_table),
__alignof__(struct dstore_node_table),
0,
NULL);
if(!dstore->dstore_node_table_cache) {
LIBLCD_ERR("failed to allocate dstore_node_table slab");
ret = -ENOMEM;
......@@ -438,6 +456,11 @@ int lcd_dstore_init_dstore(struct dstore **out)
}
*out = dstore;
/*
* Inc dstore id for next time
*/
dstore_id++;
return 0;
......
......@@ -14,8 +14,9 @@ static int boot_main(void)
struct lcd_info *mi;
cptr_t lcd;
cptr_t vfs;
cptr_t endpoint;
cptr_t dest1, dest2;
cptr_t vfs_chnl, bdi_chnl;
cptr_t pmfs_dest1, pmfs_dest2;
cptr_t vfs_dest1, vfs_dest2;
/*
* Enter lcd mode
......@@ -23,17 +24,25 @@ static int boot_main(void)
ret = lcd_enter();
if (ret) {
LIBLCD_ERR("enter");
goto fail1;
goto out;
}
/*
* Create VFS channel
*/
ret = lcd_create_sync_endpoint(&endpoint);
ret = lcd_create_sync_endpoint(&vfs_chnl);
if (ret) {
LIBLCD_ERR("create endpoint");
goto fail2;
LIBLCD_ERR("create vfs endpoint");
goto lcd_exit;
}
/*
* Create bdi channel
*/
ret = lcd_create_sync_endpoint(&bdi_chnl);
if (ret) {
LIBLCD_ERR("create bdi endpoint");
goto lcd_exit;
}
/* CREATE LCDS -------------------------------------------------- */
/*
......@@ -42,7 +51,7 @@ static int boot_main(void)
ret = klcd_create_module_klcd(&vfs, "lcd_test_mod_pmfs_vfs");
if (ret) {
LIBLCD_ERR("create vfs klcd");
goto fail2;
goto lcd_exit;
}
/*
* Create pmfs lcd
......@@ -51,38 +60,61 @@ static int boot_main(void)
LCD_CPTR_NULL, &mi);
if (ret) {
LIBLCD_ERR("create module lcd");
goto fail3;
goto destroy_vfs;
}
/* GRANT ENDPOINT TO PMFS ------------------------------ */
/* GRANT ENDPOINTS TO PMFS ------------------------------ */
/*
* Alloc dest slot
*/
ret = __lcd_alloc_cptr(mi->cache, &dest1);
ret = __lcd_alloc_cptr(mi->cache, &pmfs_dest1);
if (ret) {
LIBLCD_ERR("failed to alloc cptr");
goto fail4;
goto destroy_both;
}
/*
* Grant
*/
ret = lcd_cap_grant(lcd, endpoint, dest1);
ret = lcd_cap_grant(lcd, vfs_chnl, pmfs_dest1);
if (ret) {
LIBLCD_ERR("failed to grant endpoint to lcd1");
goto fail5;
LIBLCD_ERR("failed to grant vfs endpoint to pmfs");
goto destroy_both;
}
/*
* Alloc dest slot
*/
ret = __lcd_alloc_cptr(mi->cache, &pmfs_dest2);
if (ret) {
LIBLCD_ERR("failed to alloc cptr");
goto destroy_both;
}
/*
* Grant
*/
ret = lcd_cap_grant(lcd, bdi_chnl, pmfs_dest2);
if (ret) {
LIBLCD_ERR("failed to grant bdi endpoint to pmfs");
goto destroy_both;
}
/* GRANT ENDPOINT TO VFS ------------------------------ */
/* GRANT ENDPOINTS TO VFS ------------------------------ */
dest2 = __cptr(3);
ret = lcd_cap_grant(vfs, endpoint, dest2);
vfs_dest1 = __cptr(3);
ret = lcd_cap_grant(vfs, vfs_chnl, vfs_dest1);
if (ret) {
LIBLCD_ERR("failed to grant endpoint to vfs");
goto fail6;
LIBLCD_ERR("failed to grant vfs endpoint to vfs");
goto destroy_both;
}
vfs_dest2 = lcd_cptr_set_lvl(__cptr(0), 1);
vfs_dest2 = lcd_cptr_set_fanout(vfs_dest2, 0, 0);
vfs_dest2 = lcd_cptr_set_slot(vfs_dest2, 0);
ret = lcd_cap_grant(vfs, bdi_chnl, vfs_dest2);
if (ret) {
LIBLCD_ERR("failed to grant bdi endpoint to vfs");
goto destroy_both;
}
/* DUMP BOOT INFO FOR PMFS ------------------------------ */
/*
......@@ -91,9 +123,10 @@ static int boot_main(void)
ret = lcd_dump_boot_info(mi);
if (ret) {
LIBLCD_ERR("dump boot info");
goto fail7;
goto destroy_both;
}
to_boot_info(mi)->cptrs[0] = dest1;
to_boot_info(mi)->cptrs[0] = pmfs_dest1;
to_boot_info(mi)->cptrs[1] = pmfs_dest2;
/* RUN -------------------------------------------------- */
......@@ -103,7 +136,7 @@ static int boot_main(void)
ret = lcd_run(vfs);
if (ret) {
LIBLCD_ERR("run vfs");
goto fail8;
goto destroy_both;
}
/*
* Run pmfs
......@@ -111,7 +144,7 @@ static int boot_main(void)
ret = lcd_run(lcd);
if (ret) {
LIBLCD_ERR("run pmfs");
goto fail9;
goto destroy_both;
}
/*
* Wait for 2 seconds
......@@ -121,22 +154,16 @@ static int boot_main(void)
* Tear everything down
*/
ret = 0;
goto out;
goto destroy_both;
out:
fail9:
fail8:
fail7:
fail6:
fail5:
fail4:
destroy_both:
lcd_destroy_module_lcd(lcd, mi, LCD_CPTR_NULL);
fail3:
destroy_vfs:
klcd_destroy_module_klcd(vfs, "lcd_test_mod_pmfs_vfs");
fail2:
lcd_exit:
/* frees endpoint */
lcd_exit(0);
fail1:
out:
return ret;
}
......
/*
* bdi_caller.c - caller side of bdi interface
*/
#include <linux/backing-dev.h>
#include <lcd-domains/liblcd.h>
#include "../internal.h"
int bdi_init(struct backing_dev_info *bdi)
static cptr_t bdi_chnl;
static struct dstore *bdi_dstore;
//static struct dispatch_ctx *loop_ctx;
/* INIT/EXIT -------------------------------------------------- */
int glue_bdi_init(cptr_t _bdi_channel, struct dispatch_ctx *ctx)
{
int ret;
/* Store a reference to the dispatch loop context, so we
* can dynamically add channels to the loop later. */
// loop_ctx = ctx;
/* Store reference to bdi channel so we can invoke functions
* on it later. */
bdi_chnl = _bdi_channel;
/* Initialize data store. */
ret = lcd_dstore_init_dstore(&bdi_dstore);
if (ret) {
LIBLCD_ERR("dstore init");
return ret;
}
return 0;
}
void glue_bdi_exit(void)
{
/*
* Free bdi data store
*/
lcd_dstore_destroy(bdi_dstore);
}
/* CALLER FUNCTIONS -------------------------------------------------- */
int bdi_init(struct backing_dev_info *bdi)
{
struct backing_dev_info_container *bdi_container;
int ret;
/*
* Get container
*/
bdi_container = container_of(bdi,
struct backing_dev_info_container,
backing_dev_info);
/*
* INSERT INTO DATA STORE ------------------------------
*
*/
ret = lcd_dstore_insert(bdi_dstore,
bdi_container,
STRUCT_BACKING_DEV_INFO_TAG,
&bdi_container->my_ref);
if (ret) {
LIBLCD_ERR("lcd_dstore_insert");
lcd_exit(ret); /* abort */
}
/*
* IPC MARSHALING --------------------------------------------------
*
*/
lcd_set_r1(dptr_val(bdi_container->my_ref));
lcd_set_r2(bdi_container->backing_dev_info.ra_pages);
lcd_set_r3(bdi_container->backing_dev_info.capabilities);
/*
* IPC CALL ----------------------------------------
*/
lcd_set_r0(BDI_INIT);
ret = lcd_call(bdi_chnl);
if (ret) {
LIBLCD_ERR("lcd_call");
lcd_exit(ret);
}
/* IPC UNMARSHALING ---------------------------------------- */
/*
* We expect a remote ref coming back
*/
bdi_container->bdi_ref = __dptr(lcd_r1());
/* Clear capability register */
lcd_set_cr1(LCD_CPTR_NULL);
/*
* Pass back return value
*/
return lcd_r0();
}
void bdi_destroy(struct backing_dev_info *bdi)
{
return;
int ret;
struct backing_dev_info_container *bdi_container;
bdi_container = container_of(bdi,
struct backing_dev_info_container,
backing_dev_info);
/* IPC MARSHALING ---------------------------------------- */
/*
* Pass remote ref to bdi's copy
*/
lcd_set_r1(dptr_val(bdi_container->bdi_ref));
/* IPC CALL ---------------------------------------- */
lcd_set_r0(BDI_DESTROY);
ret = lcd_call(bdi_chnl);
if (ret) {
LIBLCD_ERR("lcd_call");
lcd_exit(ret);
}
/* POST-IPC ---------------------------------------- */
/*
* Remove bdi from data store
*/
lcd_dstore_delete(bdi_dstore, bdi_container->my_ref);
/*
* (no return value)
*/
}
......@@ -143,8 +143,6 @@ int unregister_filesystem(struct file_system_type *fs)
/* IPC CALL ---------------------------------------- */
LIBLCD_MSG("calling unregister fs");
lcd_set_r0(UNREGISTER_FS);
ret = lcd_call(vfs_chnl);
if (ret) {
......@@ -152,8 +150,6 @@ int unregister_filesystem(struct file_system_type *fs)
lcd_exit(ret);
}
LIBLCD_MSG("done");
/* POST-IPC ---------------------------------------- */
/*
......
......@@ -7,6 +7,7 @@
#include <lcd-domains/liblcd-config.h>
#include <linux/fs.h>
#include <linux/backing-dev.h>
#include <lcd-domains/liblcd.h>
#include <lcd-domains/dispatch_loop.h>
......@@ -18,10 +19,13 @@
/* Data store flags */
#define STRUCT_FILE_SYSTEM_TYPE_TAG 2
#define STRUCT_BACKING_DEV_INFO_TAG 3
/* Function flags */
#define REGISTER_FS 1
#define UNREGISTER_FS 2
#define BDI_INIT 3
#define BDI_DESTROY 4
/* STRUCT DEFS -------------------------------------------------- */
......@@ -32,11 +36,22 @@ struct file_system_type_container {
struct ipc_channel chnl;
};
struct backing_dev_info_container {
struct backing_dev_info backing_dev_info;
dptr_t my_ref;
dptr_t bdi_ref;
/* no channel since pmfs doesn't implement function ptrs */
};
/* FUNCTIONS -------------------------------------------------- */
int glue_vfs_init(cptr_t _vfs_channel, struct dispatch_ctx *ctx);
void glue_vfs_exit(void);
int glue_bdi_init(cptr_t _bdi_channel, struct dispatch_ctx *ctx);
void glue_bdi_exit(void);
#endif /* PMFS_LCD_INTERNAL_H */
......@@ -86,6 +86,7 @@ static int __noreturn __init pmfs_lcd_init(void)
{
int r = 0;
cptr_t vfs_chnl;
// cptr_t bdi_chnl;
r = lcd_enter();
if (r)
......@@ -95,27 +96,38 @@ static int __noreturn __init pmfs_lcd_init(void)
*/
init_dispatch_ctx(&ctx);
/*
* Get the vfs channel cptr from boot info
* Get the vfs and bdi channel cptrs from boot info
*/
vfs_chnl = lcd_get_boot_info()->cptrs[0];
// bdi_chnl = lcd_get_boot_info()->cptrs[1];
/*
* Initialize vfs glue
*/
r = glue_vfs_init(vfs_chnl, &ctx);
if (r) {
LIBLCD_ERR("vfs init");
goto fail1;
goto fail2;
}
/*
* Initialize bdi glue
*/
r = glue_bdi_init(vfs_chnl, &ctx);
if (r) {
LIBLCD_ERR("bdi init");
goto fail3;
}
/* EXECUTE REAL CODE ---------------------------------------- */
/*
* Initialize pmfs
*/
r = init_pmfs_fs();
if (r)
goto fail1;
goto fail4;
LIBLCD_ERR("SUCCESSFULLY REGISTERED PMFS!");
LIBLCD_MSG("SUCCESSFULLY REGISTERED PMFS!");
// loop(&ctx);
......@@ -125,8 +137,20 @@ static int __noreturn __init pmfs_lcd_init(void)
exit_pmfs_fs();
LIBLCD_ERR("SUCCESSFULLY UNREGISTERED PMFS!");
LIBLCD_MSG("SUCCESSFULLY UNREGISTERED PMFS!");
/* REAL CODE DONE; CLEAN UP ---------------------------------------- */
glue_vfs_exit();
glue_bdi_exit();
lcd_exit(0); /* doesn't return */
fail4:
glue_bdi_exit();
fail3:
glue_vfs_exit();
fail2:
fail1:
lcd_exit(r);
}
......
......@@ -25,11 +25,25 @@
#include "pmfs.h"
#include "xip.h"
#ifdef LCD_ISOLATE
struct backing_dev_info_container
pmfs_backing_dev_info_container __read_mostly = {
.backing_dev_info = {
.ra_pages = 0, /* No readahead */
.capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK,
},
};
#else /* !LCD_ISOLATE */
struct backing_dev_info pmfs_backing_dev_info __read_mostly = {
.ra_pages = 0, /* No readahead */
.capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK,
};
#endif /* LCD_ISOLATE */
unsigned int blk_type_to_shift[PMFS_BLOCK_TYPE_MAX] = {12, 21, 30};
uint32_t blk_type_to_size[PMFS_BLOCK_TYPE_MAX] = {0x1000, 0x200000, 0x40000000};
......@@ -857,8 +871,18 @@ static int pmfs_read_inode(struct inode *inode, struct pmfs_inode *pi)
inode->i_blocks = le64_to_cpu(pi->i_blocks);
inode->i_mapping->a_ops = &pmfs_aops_xip;
#ifdef LCD_ISOLATE
inode->i_mapping->backing_dev_info =
&pmfs_backing_dev_info_container.backing_dev_info;
#else /* !LCD_ISOLATE */
inode->i_mapping->backing_dev_info = &pmfs_backing_dev_info;
#endif /* LCD_ISOLATE */
switch (inode->i_mode & S_IFMT) {
case S_IFREG:
inode->i_op = &pmfs_file_inode_operations;
......
......@@ -21,6 +21,7 @@
#include <linux/pagemap.h>
#include <linux/rcupdate.h>
#include <linux/types.h>
#include <linux/backing-dev.h>
#include "journal.h"
......@@ -601,8 +602,22 @@ extern const struct inode_operations pmfs_special_inode_operations;
/* symlink.c */
extern const struct inode_operations pmfs_symlink_inode_operations;
#ifdef LCD_ISOLATE
struct backing_dev_info_container {
struct backing_dev_info backing_dev_info;
u64 ref1;
u64 ref2;
};
extern struct backing_dev_info_container pmfs_backing_dev_info_container;
#else /* !LCD_ISOLATE */
extern struct backing_dev_info pmfs_backing_dev_info;
#endif /* LCD_ISOLATE */
int pmfs_check_integrity(struct super_block *sb,
struct pmfs_super_block *super);
void *pmfs_ioremap(struct super_block *sb, phys_addr_t phys_addr,
......
......@@ -1270,11 +1270,20 @@ init_pmfs_fs(void)
rc = init_inodecache();
if (rc)
goto out2;
#if 0
#ifdef LCD_ISOLATE
rc = bdi_init(&pmfs_backing_dev_info_container.backing_dev_info);
if (rc)
goto out3;
#else /* !LCD_ISOLATE */
rc = bdi_init(&pmfs_backing_dev_info);
if (rc)
goto out3;
#endif
#endif /* LCD_ISOLATE */
#ifdef LCD_ISOLATE
......@@ -1288,15 +1297,23 @@ init_pmfs_fs(void)
if (rc)
goto out4;
#endif
#endif /* LCD_ISOLATE */
return 0;
out4:
#if 0
#ifdef LCD_ISOLATE
bdi_destroy(&pmfs_backing_dev_info_container.backing_dev_info);
#else /* !LCD_ISOLATE */
bdi_destroy(&pmfs_backing_dev_info);
#endif /* LCD_ISOLATE */
out3:
#endif
destroy_inodecache();
out2:
destroy_transaction_cache();
......@@ -1322,11 +1339,18 @@ exit_pmfs_fs(void)
unregister_filesystem(&pmfs_fs_type);
#endif
#endif /* LCD_ISOLATE */
#ifdef LCD_ISOLATE
bdi_destroy(&pmfs_backing_dev_info_container.backing_dev_info);
#else /* !LCD_ISOLATE */
#if 0
bdi_destroy(&pmfs_backing_dev_info);
#endif
#endif /* LCD_ISOLATE */
destroy_inodecache();
destroy_blocknode_cache();
destroy_transaction_cache();
......
......@@ -4,4 +4,5 @@ obj-$(CONFIG_LCD_TEST_MOD_PMFS_VFS) += lcd-test-mod-pmfs-vfs.o
lcd-test-mod-pmfs-vfs-y += main.o
# Glue
lcd-test-mod-pmfs-vfs-y += $(addprefix glue/, vfs_callee.o)
lcd-test-mod-pmfs-vfs-y += $(addprefix glue/, vfs_callee.o \
bdi_callee.o)
/*
* bdi_calle.c - callee side glue code of bdi interface
*
*/
#include <lcd-domains/dispatch_loop.h>