Commit 8269edba authored by Vikram Narayanan's avatar Vikram Narayanan
Browse files

Merge branch 'dev_netdummy' into dev_ixgbe

Conflicts:
	include/linux/netdev_features.h
	lcd-domains/config/isolated/lcd_config/post_hook.h
	lcd-domains/kliblcd/cap.c
	lcd-domains/scripts/Kbuild.test_mods
	lcd-domains/scripts/defaultconfig
	lcd-domains/scripts/unloadex
	mm/priv_mempool.c
	net/core/dev.c
parents d6c050e9 cff93fbe
......@@ -75,6 +75,7 @@ enum {
NETIF_F_HW_TC_BIT, /* Offload TC infrastructure */
NETIF_F_PRIV_DATA_POOL_BIT, /* private pool for skb->data */
NETIF_F_CHAIN_SKB_BIT,
/*
* Add your fresh new feature above and remember to update
* netdev_features_strings[] in net/core/ethtool.c and maybe
......@@ -137,6 +138,7 @@ enum {
#define NETIF_F_BUSY_POLL __NETIF_F(BUSY_POLL)
#define NETIF_F_HW_TC __NETIF_F(HW_TC)
#define NETIF_F_PRIV_DATA_POOL __NETIF_F(PRIV_DATA_POOL)
#define NETIF_F_CHAIN_SKB __NETIF_F(CHAIN_SKB)
#define for_each_netdev_feature(mask_addr, bit) \
for_each_set_bit(bit, (unsigned long *)mask_addr, NETDEV_FEATURE_COUNT)
......
......@@ -3670,6 +3670,12 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
unsigned char name_assign_type,
void (*setup)(struct net_device *),
unsigned int txqs, unsigned int rxqs);
struct net_device *alloc_netdev_mqs_lcd(int sizeof_priv, const char *name,
unsigned char name_assign_type,
void (*setup)(struct net_device *),
unsigned int txqs, unsigned int rxqs, u64 their_ref_cptr);
#define alloc_netdev(sizeof_priv, name, name_assign_type, setup) \
alloc_netdev_mqs(sizeof_priv, name, name_assign_type, setup, 1, 1)
......
......@@ -734,6 +734,7 @@ struct sk_buff {
__u8 ipvs_property:1;
__u8 inner_protocol_type:1;
__u8 remcsum_offload:1;
__u8 chain_skb:1;
/* 3 or 5 bit hole */
#ifdef CONFIG_NET_SCHED
......
......@@ -339,3 +339,4 @@ static inline void force_up_write(void *x)
#define __dynamic_netdev_dbg(desc, dev, fmt...) LIBLCD_MSG(fmt)
#define system_state 1
......@@ -75,6 +75,9 @@ int lcd_enter(void);
#ifdef LCD_ISOLATE
#define LCD_MAIN(_CODE) do { _CODE } while(0)
#else
#define LCD_MAIN(_CODE) do { _CODE } while(0)
#endif
#if 0
#define LCD_MAIN(_CODE) do { \
\
/* NULL out return address on stack so that libasync */ \
......
......@@ -26,3 +26,4 @@ obj-m += async_rpc/
obj-m += llvm_example/
obj-m += ioremap/
obj-m += ixgbe/
obj-m += nullnet/
......@@ -53,3 +53,7 @@ ioremap/lcd isolated
ixgbe/boot nonisolated
ixgbe/ixgbe_lcd isolated
ixgbe/net_klcd nonisolated
nullnet/boot nonisolated
nullnet/dummy_lcd isolated
nullnet/net_klcd nonisolated
#! /bin/bash -e
sudo rmmod lcd_test_mod_$@_boot
sudo rmmod build/test_mods/$@/boot/lcd_test_mod_$@_boot.ko
obj-$(LCD_CONFIG_BUILD_NULLNET_BOOT) += boot/
obj-$(LCD_CONFIG_BUILD_NULLNET_DUMMY_LCD) += dummy_lcd/
obj-$(LCD_CONFIG_BUILD_NULLNET_NET_KLCD) += net_klcd/
obj-m += lcd_test_mod_nullnet_boot.o
lcd_test_mod_nullnet_boot-y += main.o
ccflags-y += $(NONISOLATED_CFLAGS)
/*
* boot.c - non-isolated kernel module, does setup
* when fake minix and vfs are to be launched
* in isolated containers
*/
#include <lcd_config/pre_hook.h>
#include <liblcd/liblcd.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
#include "../glue_helper.h"
#include <lcd_config/post_hook.h>
cptr_t net_klcd, dummy_lcd;
struct lcd_create_ctx *dummy_ctx;
cptr_t net_chnl;
cptr_t net_chnl_domain_cptr, dummy_chnl_domain_cptr;
static int boot_main(void)
{
int ret;
/*
* Enter lcd mode
*/
ret = lcd_enter();
if (ret) {
LIBLCD_ERR("lcd enter failed");
goto fail1;
}
/* ---------- Create vfs channel ---------- */
ret = lcd_create_sync_endpoint(&net_chnl);
if (ret) {
LIBLCD_ERR("lcd create sync endpoint");
goto fail2;
}
/* ---------- Create LCDs ---------- */
ret = lcd_create_module_klcd(LCD_DIR("nullnet/net_klcd"),
"lcd_test_mod_nullnet_net_klcd",
&net_klcd);
if (ret) {
LIBLCD_ERR("failed to create net klcd");
goto fail3;
}
ret = lcd_create_module_lcd(LCD_DIR("nullnet/dummy_lcd"),
"lcd_test_mod_nullnet_dummy_lcd",
&dummy_lcd,
&dummy_ctx);
if (ret) {
LIBLCD_ERR("failed to create dummy lcd");
goto fail4;
}
ret = cptr_alloc(lcd_to_boot_cptr_cache(dummy_ctx),
&dummy_chnl_domain_cptr);
if (ret) {
LIBLCD_ERR("alloc cptr");
goto fail5;
}
ret = lcd_cap_grant(dummy_lcd, net_chnl, dummy_chnl_domain_cptr);
if (ret) {
LIBLCD_ERR("grant");
goto fail6;
}
/* ---------- Set up boot info ---------- */
// HACK: But WTF is this?
net_chnl_domain_cptr = __cptr(3);
ret = lcd_cap_grant(net_klcd, net_chnl, net_chnl_domain_cptr);
if (ret) {
LIBLCD_ERR("grant");
goto fail7;
}
lcd_to_boot_info(dummy_ctx)->cptrs[0] = dummy_chnl_domain_cptr;
/* ---------- RUN! ---------- */
LIBLCD_MSG("starting network...");
ret = lcd_run(net_klcd);
if (ret) {
LIBLCD_ERR("failed to start vfs lcd");
goto fail8;
}
LIBLCD_MSG("starting dummy ethernet...");
ret = lcd_run(dummy_lcd);
if (ret) {
LIBLCD_ERR("failed to start dummy lcd");
goto fail9;
}
/*
* Wait for 4 seconds
*/
//msleep(100000);
/*
* Tear everything down
*/
ret = 0;
// return
goto fail1;
/* The destroy's will free up everything ... */
fail9:
fail8:
fail7:
lcd_cap_delete(dummy_lcd);
lcd_destroy_create_ctx(dummy_ctx);
fail6:
fail5:
fail4:
//lcd_cap_delete(net_klcd);
lcd_destroy_module_klcd(net_klcd, "lcd_test_mod_nullnet_net_klcd");
fail3:
fail2:
lcd_exit(0); /* will free endpoints */
fail1:
return ret;
}
static DECLARE_WAIT_QUEUE_HEAD(wq);
static int shutdown = 0;
int boot_lcd_thread(void *data)
{
static unsigned once = 0;
int ret;
while (!kthread_should_stop()) {
if (!once) {
LCD_MAIN({
ret = boot_main();
});
}
once = 1;
wait_event_interruptible(wq, shutdown != 0);
}
msleep(2000);
LIBLCD_MSG("Exiting thread");
lcd_destroy_module_klcd(net_klcd,
"lcd_test_mod_nullnet_net_klcd");
if (current->lcd)
lcd_cap_delete(dummy_lcd);
if (dummy_ctx)
lcd_destroy_create_ctx(dummy_ctx);
lcd_exit(0);
return 0;
}
struct task_struct *boot_task;
static int boot_init(void)
{
LIBLCD_MSG("%s: entering", __func__);
boot_task = kthread_create(boot_lcd_thread, NULL, "boot_lcd_thread");
if (!IS_ERR(boot_task))
wake_up_process(boot_task);
return 0;
}
static void boot_exit(void)
{
/* nothing to do */
if (!IS_ERR(boot_task)) {
LIBLCD_MSG("%s: exiting", __func__);
shutdown = 1;
wake_up_interruptible(&wq);
kthread_stop(boot_task);
}
}
module_init(boot_init);
module_exit(boot_exit);
MODULE_LICENSE("GPL");
/*
* cap.c
*
* cspace code for pmfs/vfs
*/
#include <lcd_config/pre_hook.h>
#include <libcap.h>
#include <liblcd/liblcd.h>
#include <linux/slab.h>
#include "glue_helper.h"
#include <lcd_config/post_hook.h>
/* ------------------------------------------------------------ */
static struct cap_type_system *glue_libcap_type_system;
struct type_ops_id {
struct cap_type_ops ops;
cap_type_t libcap_type;
};
enum glue_type {
GLUE_TYPE_NET_DEVICE,
GLUE_TYPE_NET_DEVICE_OPS,
GLUE_TYPE_NLATTR,
GLUE_TYPE_RTNL_LINK_OPS,
GLUE_TYPE_RTNL_LINK_STATS64,
GLUE_TYPE_SK_BUFF,
GLUE_TYPE_SETUP,
GLUE_NR_TYPES,
};
static int dummy_func(struct cspace *cspace, struct cnode *cnode,
void *object)
{
return 0;
}
static struct type_ops_id glue_libcap_type_ops[GLUE_NR_TYPES] = {
{
{
.name = "struct net_device",
.delete = dummy_func,
.revoke = dummy_func,
}
},
{
{
.name = "struct net_device_ops",
.delete = dummy_func,
.revoke = dummy_func,
}
},
{
{
.name = "struct nlattr",
.delete = dummy_func,
.revoke = dummy_func,
}
},
{
{
.name = "struct rtnl_link_ops",
.delete = dummy_func,
.revoke = dummy_func,
}
},
{
{
.name = "struct rtnl_link_stats64",
.delete = dummy_func,
.revoke = dummy_func,
}
},
{
{
.name = "struct sk_buff",
.delete = dummy_func,
.revoke = dummy_func,
}
},
{
{
.name = "alloc_netdev_mqs: setup",
.delete = dummy_func,
.revoke = dummy_func,
}
},
};
int glue_cap_init(void)
{
int ret;
int i;
cap_type_t libcap_type;
/*
* Alloc and init microkernel type system
*/
ret = cap_type_system_alloc(&glue_libcap_type_system);
if (ret) {
LIBLCD_ERR("alloc glue type system failed");
goto fail1;
}
ret = cap_type_system_init(glue_libcap_type_system);
if (ret) {
LIBLCD_ERR("init glue type system failed");
goto fail2;
}
/*
* Add types
*/
for (i = 0; i < GLUE_NR_TYPES; i++) {
libcap_type = cap_register_private_type(
glue_libcap_type_system,
0,
&glue_libcap_type_ops[i].ops);
if (libcap_type == CAP_TYPE_ERR) {
LIBLCD_ERR("failed to register glue cap type %s",
glue_libcap_type_ops[i].ops.name);
ret = -EIO;
goto fail3;
}
glue_libcap_type_ops[i].libcap_type = libcap_type;
}
return 0;
fail3:
cap_type_system_destroy(glue_libcap_type_system);
fail2:
cap_type_system_free(glue_libcap_type_system);
glue_libcap_type_system = NULL;
fail1:
return ret;
}
int glue_cap_create(struct glue_cspace **cspace_out)
{
return glue_cspace_alloc_init(glue_libcap_type_system, cspace_out);
}
void glue_cap_destroy(struct glue_cspace *cspace)
{
glue_cspace_destroy_free(cspace);
}
void glue_cap_exit(void)
{
/*
* Destroy and free type system if necessary
*/
if (glue_libcap_type_system) {
cap_type_system_destroy(glue_libcap_type_system);
cap_type_system_free(glue_libcap_type_system);
glue_libcap_type_system = NULL;
}
}
int glue_cap_insert_net_device_type(
struct glue_cspace *cspace,
struct net_device_container *net_device_container,
cptr_t *c_out)
{
return glue_cspace_insert(cspace, net_device_container,
glue_libcap_type_ops[GLUE_TYPE_NET_DEVICE].libcap_type,
c_out);
}
int glue_cap_insert_net_device_ops_type(
struct glue_cspace *cspace,
struct net_device_ops_container *net_device_ops_container,
cptr_t *c_out)
{
return glue_cspace_insert(cspace, net_device_ops_container,
glue_libcap_type_ops[GLUE_TYPE_NET_DEVICE_OPS].libcap_type,
c_out);
}
int glue_cap_insert_nlattr_type(
struct glue_cspace *cspace,
struct nlattr_container *nlattr_container,
cptr_t *c_out)
{
return glue_cspace_insert(cspace, nlattr_container,
glue_libcap_type_ops[GLUE_TYPE_NLATTR].libcap_type,
c_out);
}
int glue_cap_insert_rtnl_link_ops_type(
struct glue_cspace *cspace,
struct rtnl_link_ops_container *rtnl_link_ops_container,
cptr_t *c_out)
{
return glue_cspace_insert(cspace, rtnl_link_ops_container,
glue_libcap_type_ops[GLUE_TYPE_RTNL_LINK_OPS].libcap_type,
c_out);
}
int glue_cap_insert_rtnl_link_stats64_type(
struct glue_cspace *cspace,
struct rtnl_link_stats64_container *rtnl_link_stats64_container,
cptr_t *c_out)
{
return glue_cspace_insert(cspace, rtnl_link_stats64_container,
glue_libcap_type_ops[GLUE_TYPE_RTNL_LINK_STATS64].libcap_type,
c_out);
}
int glue_cap_insert_sk_buff_type(
struct glue_cspace *cspace,
struct sk_buff_container *sk_buff_container,
cptr_t *c_out)
{
return glue_cspace_insert(cspace, sk_buff_container,
glue_libcap_type_ops[GLUE_TYPE_SK_BUFF].libcap_type,
c_out);
}
int glue_cap_insert_setup_type(
struct glue_cspace *cspace,
struct setup_container *setup_container,
cptr_t *c_out)
{
return glue_cspace_insert(cspace, setup_container,
glue_libcap_type_ops[GLUE_TYPE_SETUP].libcap_type,
c_out);
}
int glue_cap_lookup_net_device_type(
struct glue_cspace *cspace,
cptr_t c,
struct net_device_container **net_device_container)
{
return glue_cspace_lookup(cspace, c,
glue_libcap_type_ops[GLUE_TYPE_NET_DEVICE].libcap_type,
(void **)net_device_container);
}
int glue_cap_lookup_net_device_ops_type(
struct glue_cspace *cspace,
cptr_t c,
struct net_device_ops_container **net_device_ops_container)
{
return glue_cspace_lookup(cspace, c,
glue_libcap_type_ops[GLUE_TYPE_NET_DEVICE_OPS].libcap_type,
(void **)net_device_ops_container);
}
int glue_cap_lookup_nlattr_type(
struct glue_cspace *cspace,
cptr_t c,
struct nlattr_container **nlattr_container)
{
return glue_cspace_lookup(
cspace, c,
glue_libcap_type_ops[GLUE_TYPE_NLATTR].libcap_type,
(void **)nlattr_container);
}
int glue_cap_lookup_rtnl_link_ops_type(
struct glue_cspace *cspace,
cptr_t c,
struct rtnl_link_ops_container **rtnl_link_ops_container)
{
return glue_cspace_lookup(
cspace, c,
glue_libcap_type_ops[GLUE_TYPE_RTNL_LINK_OPS].libcap_type,
(void **)rtnl_link_ops_container);
}
int glue_cap_lookup_rtnl_link_stats64_type(
struct glue_cspace *cspace,
cptr_t c,
struct rtnl_link_stats64_container **rtnl_link_stats64_container)
{
return glue_cspace_lookup(
cspace, c,
glue_libcap_type_ops[GLUE_TYPE_RTNL_LINK_STATS64].libcap_type,
(void **)rtnl_link_stats64_container);
}
int glue_cap_lookup_sk_buff_type(
struct glue_cspace *cspace,
cptr_t c,
struct sk_buff_container **sk_buff_container)
{
return glue_cspace_lookup(
cspace, c,
glue_libcap_type_ops[GLUE_TYPE_SK_BUFF].libcap_type,
(void **)sk_buff_container);
}
int glue_cap_lookup_setup_type(
struct glue_cspace *cspace,
cptr_t c,
struct setup_container **setup_container)
{
return glue_cspace_lookup(
cspace, c,
glue_libcap_type_ops[GLUE_TYPE_SETUP].libcap_type,
(void **)setup_container);
}
void glue_cap_remove(
struct glue_cspace *cspace,
cptr_t c)
{
glue_cspace_remove(cspace, c);
}
obj-m += lcd_test_mod_nullnet_dummy_lcd.o
lcd_test_mod_nullnet_dummy_lcd-y += main.o
# Original code
lcd_test_mod_nullnet_dummy_lcd-y += dummy.o
lcd_test_mod_nullnet_dummy_lcd-y += $(LIBLCD)
# glue code
lcd_test_mod_nullnet_dummy_lcd-y += $(addprefix glue/, nullnet_caller.o \
dispatch.o )
lcd_test_mod_nullnet_dummy_lcd-y += $(addprefix ../, cap.o)
ccflags-y += $(ISOLATED_CFLAGS)
/* dummy.c: a dummy net driver
The purpose of this driver is to provide a device to point a
route through, but not to actually transmit packets.
Why? If you have a machine whose only connection is an occasional