Skip to content

Commit

Permalink
Refactor XDPLua to reduce its footprint
Browse files Browse the repository at this point in the history
  • Loading branch information
VictorNogueiraRio committed Jan 16, 2021
1 parent 69676b4 commit 3884fca
Show file tree
Hide file tree
Showing 20 changed files with 405 additions and 786 deletions.
4 changes: 0 additions & 4 deletions include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -3587,10 +3587,6 @@ u32 __dev_xdp_query(struct net_device *dev, bpf_op_t xdp_op,
enum bpf_netdev_command cmd);
int xdp_umem_query(struct net_device *dev, u16 queue_id);

#ifdef CONFIG_XDP_LUA
int generic_xdp_lua_install_prog(char *lua_prog);
#endif /* CONFIG_XDP_LUA */

int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
int dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
bool is_skb_forwardable(const struct net_device *dev,
Expand Down
17 changes: 0 additions & 17 deletions include/net/xdp.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,30 +63,13 @@ struct xdp_rxq_info {
struct xdp_mem_info mem;
} ____cacheline_aligned; /* perf critical, avoid false-sharing */

#ifdef CONFIG_XDP_LUA
struct xdplua_create_work {
char lua_script[8192];
struct lua_State *L;
struct work_struct work;
spinlock_t lock;
bool init;
};

DECLARE_PER_CPU(struct xdplua_create_work, luaworks);
#endif /* CONFIG_XDP_LUA */


struct xdp_buff {
void *data;
void *data_end;
void *data_meta;
void *data_hard_start;
unsigned long handle;
struct xdp_rxq_info *rxq;
#ifdef CONFIG_XDP_LUA
struct sk_buff *skb;
struct lua_State *L;
#endif /* CONFIG_XDP_LUA */
};

struct xdp_frame {
Expand Down
77 changes: 77 additions & 0 deletions include/net/xdplua.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/* XDPLua internal functions
* Copyright (C) 2021 Victor Nogueira <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __LINUX_NET_XDP_LUA_H__
#define __LINUX_NET_XDP_LUA_H__

#include <lua.h>

#include <linux/skbuff.h>
#include <linux/workqueue.h>
#include <uapi/linux/if_link.h>
#include <linux/filter.h>

struct xdp_lua_work {
char script[XDP_LUA_MAX_SCRIPT_LEN];
struct lua_State *L;
struct sk_buff *skb;
struct work_struct work;
};

DECLARE_PER_CPU(struct xdp_lua_work, luaworks);

#define XDP_LUA_BPF_FUNC(name) BPF_FUNC_lua_##name

#define xdp_lua_get_skb() (this_cpu_ptr(&luaworks)->skb)
#define xdp_lua_set_skb(skb) (this_cpu_ptr(&luaworks)->skb = skb)

void generic_xdp_lua_install_prog(const char *script);
void xdp_lua_init(void);

#define __BPF_LUA_MAP_0(l, m, v, ...) l
#define __BPF_LUA_MAP_1(l, m, v, t, a, ...) l, __BPF_MAP_1(m, v, t, a, __VA_ARGS__)
#define __BPF_LUA_MAP_2(l, m, v, t, a, ...) l, __BPF_MAP_2(m, v, t, a, __VA_ARGS__)
#define __BPF_LUA_MAP_3(l, m, v, t, a, ...) l, __BPF_MAP_3(m, v, t, a, __VA_ARGS__)
#define __BPF_LUA_MAP_4(l, m, v, t, a, ...) l, __BPF_MAP_4(m, v, t, a, __VA_ARGS__)
#define __BPF_LUA_MAP_5(l, m, v, t, a, ...) l, __BPF_MAP_5(m, v, t, a, __VA_ARGS__)

#define __BPF_LUA_MAP(n, l, ...) __BPF_LUA_MAP_##n(l, __VA_ARGS__)

#define LST_TYPE lua_State
#define LST_NAME L
#define LST_DECL __BPF_DECL_ARGS(LST_TYPE*, LST_NAME)

#define BPF_LUA_CALL_x(x, name, ...) \
static __always_inline \
u64 ____##name(__BPF_LUA_MAP(x, LST_DECL, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__)); \
u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__)); \
u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__)) \
{ \
int ret = -ENOENT; \
lua_State *L = this_cpu_ptr(&luaworks)->L; \
WARN_ON(!L); \
if (!L) \
return ret; \
ret = ____##name(__BPF_LUA_MAP(x, LST_NAME, __BPF_CAST, __BPF_N, __VA_ARGS__)); \
return ret; \
} \
static __always_inline \
u64 ____##name(__BPF_LUA_MAP(x, LST_DECL, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__))

#define BPF_LUA_CALL_0(name, ...) BPF_LUA_CALL_x(0, name, __VA_ARGS__)
#define BPF_LUA_CALL_1(name, ...) BPF_LUA_CALL_x(1, name, __VA_ARGS__)
#define BPF_LUA_CALL_2(name, ...) BPF_LUA_CALL_x(2, name, __VA_ARGS__)
#define BPF_LUA_CALL_3(name, ...) BPF_LUA_CALL_x(3, name, __VA_ARGS__)
#define BPF_LUA_CALL_4(name, ...) BPF_LUA_CALL_x(4, name, __VA_ARGS__)
#define BPF_LUA_CALL_5(name, ...) BPF_LUA_CALL_x(5, name, __VA_ARGS__)

#endif /* __LINUX_NET_XDP_LUA_H__ */
1 change: 1 addition & 0 deletions include/uapi/linux/if_link.h
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,7 @@ enum {
#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | \
XDP_FLAGS_MODES)

#define XDP_LUA_MAX_SCRIPT_LEN 8192
/* These are stored into IFLA_XDP_ATTACHED on dump. */
enum {
XDP_ATTACHED_NONE = 0,
Expand Down
7 changes: 4 additions & 3 deletions net/core/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ obj-y := sock.o request_sock.o skbuff.o datagram.o stream.o scm.o \

obj-$(CONFIG_SYSCTL) += sysctl_net_core.o

CFLAGS_dev.o = -Ilib/lunatik/lua/ -D_KERNEL \
-Ilib/luadata/
CFLAGS_dev.o = -Ilib/lunatik/lua/ -D_KERNEL
CFLAGS_filter.o = -Ilib/lunatik/lua/ -D_KERNEL \
-Ilib/luadata/ -Ilib/luaunpack/
CFLAGS_rtnetlink.o = -Ilib/lunatik/lua/ -D_KERNEL
CFLAGS_xdplua.o = -Ilib/lunatik/lua/ -Ilib/luadata -D_KERNEL
obj-y += dev.o ethtool.o dev_addr_lists.o dst.o netevent.o \
neighbour.o rtnetlink.o utils.o link_watch.o filter.o \
sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \
fib_notifier.o xdp.o
fib_notifier.o xdp.o xdplua.o

obj-y += net-sysfs.o
obj-$(CONFIG_PAGE_POOL) += page_pool.o
Expand Down
76 changes: 7 additions & 69 deletions net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,6 @@
* - netif_rx() feedback
*/

#ifdef CONFIG_XDP_LUA
#include <lua.h>
#include <lauxlib.h>
#include <lstate.h>
#include <lualib.h>
#include <luadata.h>
#endif /* CONFIG_XDP_LUA */

#include <linux/uaccess.h>
#include <linux/bitops.h>
#include <linux/capability.h>
Expand Down Expand Up @@ -164,8 +156,9 @@
static DEFINE_SPINLOCK(ptype_lock);
static DEFINE_SPINLOCK(offload_lock);
#ifdef CONFIG_XDP_LUA
DEFINE_PER_CPU(struct xdplua_create_work, luaworks);
#endif
#include <net/xdplua.h>
#undef free
#endif /* CONFIG_XDP_LUA */
struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly;
struct list_head ptype_all __read_mostly; /* Taps */
static struct list_head offload_base __read_mostly;
Expand Down Expand Up @@ -4290,9 +4283,6 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,
u32 metalen, act = XDP_DROP;
int hlen, off;
u32 mac_len;
#ifdef CONFIG_XDP_LUA
struct xdplua_create_work *lw;
#endif /* CONFIG_XDP_LUA */

/* Reinjected packets coming from act_mirred or similar should
* not get XDP generic processing.
Expand Down Expand Up @@ -4335,21 +4325,11 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,
rxqueue = netif_get_rxqueue(skb);
xdp->rxq = &rxqueue->xdp_rxq;
#ifdef CONFIG_XDP_LUA
lw = this_cpu_ptr(&luaworks);

xdp->skb = skb;
xdp->L = lw->L;
xdp_lua_set_skb(skb);
#endif /* CONFIG_XDP_LUA */

act = bpf_prog_run_xdp(xdp_prog, xdp);

#ifdef CONFIG_XDP_LUA
if (lw->init) {
lw->init = false;
spin_unlock(&lw->lock);
}
#endif /* CONFIG_XDP_LUA */

off = xdp->data - orig_data;
if (off > 0)
__skb_pull(skb, off);
Expand Down Expand Up @@ -5115,35 +5095,6 @@ static int generic_xdp_install(struct net_device *dev, struct netdev_bpf *xdp)
return ret;
}

#ifdef CONFIG_XDP_LUA

static void per_cpu_xdp_lua_install(struct work_struct *w) {
int this_cpu = smp_processor_id();
struct xdplua_create_work *lw =
container_of(w, struct xdplua_create_work, work);

spin_lock_bh(&lw->lock);
if (luaL_dostring(lw->L, lw->lua_script)) {
pr_err(KERN_INFO "error: %s\nOn cpu: %d\n",
lua_tostring(lw->L, -1), this_cpu);
}
spin_unlock_bh(&lw->lock);
}

int generic_xdp_lua_install_prog(char *lua_script)
{
int cpu;
struct xdplua_create_work *lw;

for_each_possible_cpu(cpu) {
lw = per_cpu_ptr(&luaworks, cpu);
strcpy(lw->lua_script, lua_script);
schedule_work_on(cpu, &lw->work);
}
return 0;
}
#endif /* CONFIG_XDP_LUA */

static int netif_receive_skb_internal(struct sk_buff *skb)
{
int ret;
Expand Down Expand Up @@ -9651,9 +9602,6 @@ static int __init net_dev_init(void)
for_each_possible_cpu(i) {
struct work_struct *flush = per_cpu_ptr(&flush_works, i);
struct softnet_data *sd = &per_cpu(softnet_data, i);
#ifdef CONFIG_XDP_LUA
struct xdplua_create_work *lw = per_cpu_ptr(&luaworks, i);
#endif

INIT_WORK(flush, flush_backlog);

Expand All @@ -9673,19 +9621,6 @@ static int __init net_dev_init(void)
init_gro_hash(&sd->backlog);
sd->backlog.poll = process_backlog;
sd->backlog.weight = weight_p;
#ifdef CONFIG_XDP_LUA
lw->L = luaL_newstate();
WARN_ON(!lw->L);

if (!lw->L)
continue;

luaL_openlibs(lw->L);
luaL_requiref(lw->L, "data", luaopen_data, 1);
lua_pop(lw->L, 1);

INIT_WORK(&lw->work, per_cpu_xdp_lua_install);
#endif /* CONFIG_XDP_LUA */
}

dev_boot_phase = 0;
Expand All @@ -9710,6 +9645,9 @@ static int __init net_dev_init(void)

rc = cpuhp_setup_state_nocalls(CPUHP_NET_DEV_DEAD, "net/dev:dead",
NULL, dev_cpu_dead);
#ifdef CONFIG_XDP_LUA
xdp_lua_init();
#endif /* CONFIG_XDP_LUA */
WARN_ON(rc < 0);
rc = 0;
out:
Expand Down
Loading

0 comments on commit 3884fca

Please sign in to comment.