Skip to content

Commit 5eb463c

Browse files
Fix script loading synchronization issue
1 parent 13a42eb commit 5eb463c

7 files changed

Lines changed: 98 additions & 81 deletions

File tree

include/linux/filter.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,14 +1268,4 @@ struct bpf_sockopt_kern {
12681268
s32 retval;
12691269
};
12701270

1271-
#ifdef CONFIG_XDP_LUA
1272-
extern struct list_head lua_state_cpu_list;
1273-
1274-
struct lua_state_cpu {
1275-
struct lua_State *L;
1276-
int cpu;
1277-
struct list_head list;
1278-
};
1279-
#endif /* CONFIG_XDP_LUA */
1280-
12811271
#endif /* __LINUX_FILTER_H__ */

include/net/xdp.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,19 @@ struct xdp_rxq_info {
6363
struct xdp_mem_info mem;
6464
} ____cacheline_aligned; /* perf critical, avoid false-sharing */
6565

66+
#ifdef CONFIG_XDP_LUA
67+
struct xdplua_create_work {
68+
char lua_script[8192];
69+
struct lua_State *L;
70+
struct work_struct work;
71+
spinlock_t lock;
72+
bool init;
73+
};
74+
75+
DECLARE_PER_CPU(struct xdplua_create_work, luaworks);
76+
#endif /* CONFIG_XDP_LUA */
77+
78+
6679
struct xdp_buff {
6780
void *data;
6881
void *data_end;

include/uapi/linux/bpf.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2951,10 +2951,6 @@ union bpf_attr {
29512951
* so the memory at s can be freed or reused immediately after the
29522952
* function returns.
29532953
*
2954-
* void bpf_lua_setstate(void *ctx)
2955-
* Description
2956-
* Sets the Lua state pointer in the context struct
2957-
*
29582954
* int bpf_lua_toboolean(void *ctx, int index)
29592955
* Description
29602956
* Converts the Lua value at the given index to a C
@@ -3103,7 +3099,6 @@ union bpf_attr {
31033099
FN(lua_pushmap), \
31043100
FN(lua_pushskb), \
31053101
FN(lua_pushstring), \
3106-
FN(lua_setstate), \
31073102
FN(lua_toboolean), \
31083103
FN(lua_tointeger),
31093104
/* #endif CONFIG_XDP_LUA */

net/core/dev.c

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
#ifdef CONFIG_XDP_LUA
7272
#include <lua.h>
7373
#include <lauxlib.h>
74+
#include <lstate.h>
7475
#include <lualib.h>
7576
#include <luadata.h>
7677
#endif /* CONFIG_XDP_LUA */
@@ -159,6 +160,9 @@
159160

160161
static DEFINE_SPINLOCK(ptype_lock);
161162
static DEFINE_SPINLOCK(offload_lock);
163+
#ifdef CONFIG_XDP_LUA
164+
DEFINE_PER_CPU(struct xdplua_create_work, luaworks);
165+
#endif
162166
struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly;
163167
struct list_head ptype_all __read_mostly; /* Taps */
164168
static struct list_head offload_base __read_mostly;
@@ -171,10 +175,6 @@ static int call_netdevice_notifiers_extack(unsigned long val,
171175
struct netlink_ext_ack *extack);
172176
static struct napi_struct *napi_by_id(unsigned int napi_id);
173177

174-
#ifdef CONFIG_XDP_LUA
175-
struct list_head lua_state_cpu_list;
176-
#endif /* CONFIG_XDP_LUA */
177-
178178
/*
179179
* The @dev_base_head list is protected by @dev_base_lock and the rtnl
180180
* semaphore.
@@ -4523,6 +4523,9 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,
45234523
bool orig_bcast;
45244524
int hlen, off;
45254525
u32 mac_len;
4526+
#ifdef CONFIG_XDP_LUA
4527+
struct xdplua_create_work *lw;
4528+
#endif /* CONFIG_XDP_LUA */
45264529

45274530
/* Reinjected packets coming from act_mirred or similar should
45284531
* not get XDP generic processing.
@@ -4568,11 +4571,21 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,
45684571
rxqueue = netif_get_rxqueue(skb);
45694572
xdp->rxq = &rxqueue->xdp_rxq;
45704573
#ifdef CONFIG_XDP_LUA
4574+
lw = this_cpu_ptr(&luaworks);
4575+
45714576
xdp->skb = skb;
4577+
xdp->L = lw->L;
45724578
#endif /* CONFIG_XDP_LUA */
45734579

45744580
act = bpf_prog_run_xdp(xdp_prog, xdp);
45754581

4582+
#ifdef CONFIG_XDP_LUA
4583+
if (lw->init) {
4584+
lw->init = false;
4585+
spin_unlock(&lw->lock);
4586+
}
4587+
#endif /* CONFIG_XDP_LUA */
4588+
45764589
/* check if bpf_xdp_adjust_head was used */
45774590
off = xdp->data - orig_data;
45784591
if (off) {
@@ -5381,16 +5394,29 @@ static int generic_xdp_install(struct net_device *dev, struct netdev_bpf *xdp)
53815394
}
53825395

53835396
#ifdef CONFIG_XDP_LUA
5384-
int generic_xdp_lua_install_prog(char *lua_prog)
5397+
5398+
static void per_cpu_xdp_lua_install(struct work_struct *w) {
5399+
int this_cpu = smp_processor_id();
5400+
struct xdplua_create_work *lw =
5401+
container_of(w, struct xdplua_create_work, work);
5402+
5403+
spin_lock_bh(&lw->lock);
5404+
if (luaL_dostring(lw->L, lw->lua_script)) {
5405+
pr_err(KERN_INFO "error: %s\nOn cpu: %d\n",
5406+
lua_tostring(lw->L, -1), this_cpu);
5407+
}
5408+
spin_unlock_bh(&lw->lock);
5409+
}
5410+
5411+
int generic_xdp_lua_install_prog(char *lua_script)
53855412
{
5386-
struct lua_state_cpu *sc;
5413+
int cpu;
5414+
struct xdplua_create_work *lw;
53875415

5388-
list_for_each_entry(sc, &lua_state_cpu_list, list) {
5389-
if (luaL_dostring(sc->L, lua_prog)) {
5390-
pr_err(KERN_INFO "error: %s\nOn cpu: %d\n",
5391-
lua_tostring(sc->L, -1), sc->cpu);
5392-
return -EINVAL;
5393-
}
5416+
for_each_possible_cpu(cpu) {
5417+
lw = per_cpu_ptr(&luaworks, cpu);
5418+
strcpy(lw->lua_script, lua_script);
5419+
schedule_work_on(cpu, &lw->work);
53945420
}
53955421
return 0;
53965422
}
@@ -10492,9 +10518,6 @@ static struct pernet_operations __net_initdata default_device_ops = {
1049210518
static int __init net_dev_init(void)
1049310519
{
1049410520
int i, rc = -ENOMEM;
10495-
#ifdef CONFIG_XDP_LUA
10496-
struct lua_state_cpu *new_state_cpu;
10497-
#endif /* CONFIG_XDP_LUA */
1049810521

1049910522
BUG_ON(!dev_boot_phase);
1050010523

@@ -10509,9 +10532,6 @@ static int __init net_dev_init(void)
1050910532
INIT_LIST_HEAD(&ptype_base[i]);
1051010533

1051110534
INIT_LIST_HEAD(&offload_base);
10512-
#ifdef CONFIG_XDP_LUA
10513-
INIT_LIST_HEAD(&lua_state_cpu_list);
10514-
#endif /* CONFIG_XDP_LUA */
1051510535

1051610536
if (register_pernet_subsys(&netdev_net_ops))
1051710537
goto out;
@@ -10523,6 +10543,9 @@ static int __init net_dev_init(void)
1052310543
for_each_possible_cpu(i) {
1052410544
struct work_struct *flush = per_cpu_ptr(&flush_works, i);
1052510545
struct softnet_data *sd = &per_cpu(softnet_data, i);
10546+
#ifdef CONFIG_XDP_LUA
10547+
struct xdplua_create_work *lw = per_cpu_ptr(&luaworks, i);
10548+
#endif
1052610549

1052710550
INIT_WORK(flush, flush_backlog);
1052810551

@@ -10542,25 +10565,18 @@ static int __init net_dev_init(void)
1054210565
init_gro_hash(&sd->backlog);
1054310566
sd->backlog.poll = process_backlog;
1054410567
sd->backlog.weight = weight_p;
10545-
1054610568
#ifdef CONFIG_XDP_LUA
10547-
new_state_cpu = (struct lua_state_cpu *)
10548-
kmalloc(sizeof(struct lua_state_cpu), GFP_ATOMIC);
10549-
if (!new_state_cpu)
10550-
continue;
10569+
lw->L = luaL_newstate();
10570+
WARN_ON(!lw->L);
1055110571

10552-
new_state_cpu->L = luaL_newstate();
10553-
if (!new_state_cpu->L) {
10554-
kfree(new_state_cpu);
10572+
if (!lw->L)
1055510573
continue;
10556-
}
1055710574

10558-
luaL_openlibs(new_state_cpu->L);
10559-
luaL_requiref(new_state_cpu->L, "data", luaopen_data, 1);
10560-
lua_pop(new_state_cpu->L, 1);
10561-
new_state_cpu->cpu = i;
10575+
luaL_openlibs(lw->L);
10576+
luaL_requiref(lw->L, "data", luaopen_data, 1);
10577+
lua_pop(lw->L, 1);
1056210578

10563-
list_add(&new_state_cpu->list, &lua_state_cpu_list);
10579+
INIT_WORK(&lw->work, per_cpu_xdp_lua_install);
1056410580
#endif /* CONFIG_XDP_LUA */
1056510581
}
1056610582

net/core/filter.c

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5855,10 +5855,22 @@ static const struct bpf_func_proto bpf_tcp_gen_syncookie_proto = {
58555855
#endif /* CONFIG_INET */
58565856

58575857
#ifdef CONFIG_XDP_LUA
5858+
5859+
static inline void verify_and_lock(void) {
5860+
struct xdplua_create_work *lw;
5861+
5862+
lw = this_cpu_ptr(&luaworks);
5863+
if (!lw->init) {
5864+
lw->init = true;
5865+
spin_lock(&lw->lock);
5866+
}
5867+
}
5868+
58585869
BPF_CALL_2(bpf_lua_dataref, struct xdp_buff *, ctx, int, offset) {
58595870
if (offset + ctx->data < ctx->data_end) {
58605871
int data_ref;
58615872

5873+
verify_and_lock();
58625874
data_ref = ldata_newref(ctx->L, ctx->data + offset,
58635875
ctx->data_end - ctx->data - offset);
58645876
return data_ref;
@@ -5877,6 +5889,7 @@ static const struct bpf_func_proto bpf_lua_dataref_proto = {
58775889
};
58785890

58795891
BPF_CALL_2(bpf_lua_dataunref, struct xdp_buff *, ctx, int, data_ref) {
5892+
verify_and_lock();
58805893
ldata_unref(ctx->L, data_ref);
58815894
return 0;
58825895
}
@@ -5892,18 +5905,28 @@ static const struct bpf_func_proto bpf_lua_dataunref_proto = {
58925905

58935906
BPF_CALL_4(bpf_lua_pcall, struct xdp_buff *, ctx, char *, funcname,
58945907
int, num_args, int, num_rets) {
5908+
int base;
5909+
5910+
verify_and_lock();
5911+
5912+
base = lua_gettop(ctx->L) - num_args;
58955913
if (lua_getglobal(ctx->L, funcname) != LUA_TFUNCTION) {
58965914
pr_err("function %s not found\n", funcname);
5897-
lua_pop(ctx->L, num_args);
5898-
return 0;
5915+
num_rets = 0;
5916+
goto clean_state;
58995917
}
59005918

5901-
lua_insert(ctx->L, 1);
5919+
lua_insert(ctx->L, base + 1);
59025920
if (lua_pcall(ctx->L, num_args, num_rets, 0)) {
59035921
pr_err("%s\n", lua_tostring(ctx->L, -1));
5904-
lua_pop(ctx->L, 1);
5905-
return 0;
5922+
num_rets = 0;
5923+
goto clean_state;
59065924
}
5925+
5926+
base += num_rets;
5927+
5928+
clean_state:
5929+
lua_settop(ctx->L, base);
59075930
return num_rets;
59085931
}
59095932

@@ -5919,6 +5942,7 @@ static const struct bpf_func_proto bpf_lua_pcall_proto = {
59195942
};
59205943

59215944
BPF_CALL_2(bpf_lua_pop, struct xdp_buff *, ctx, int, index) {
5945+
verify_and_lock();
59225946
lua_pop(ctx->L, index);
59235947
return 0;
59245948
}
@@ -5933,6 +5957,7 @@ static const struct bpf_func_proto bpf_lua_pop_proto = {
59335957
};
59345958

59355959
BPF_CALL_2(bpf_lua_pushinteger, struct xdp_buff *, ctx, int, num) {
5960+
verify_and_lock();
59365961
lua_pushinteger(ctx->L, num);
59375962
return 0;
59385963
}
@@ -5947,6 +5972,7 @@ static const struct bpf_func_proto bpf_lua_pushinteger_proto = {
59475972
};
59485973

59495974
BPF_CALL_2(bpf_lua_pushlightuserdata, struct xdp_buff *, ctx, void *, ptr) {
5975+
verify_and_lock();
59505976
lua_pushlightuserdata(ctx->L, ptr);
59515977
return 0;
59525978
}
@@ -5961,6 +5987,7 @@ static const struct bpf_func_proto bpf_lua_pushlightuserdata_proto = {
59615987
};
59625988

59635989
BPF_CALL_2(bpf_lua_pushmap, struct xdp_buff *, ctx, struct bpf_map *, map) {
5990+
verify_and_lock();
59645991
lua_pushlightuserdata(ctx->L, map);
59655992
return 0;
59665993
}
@@ -5975,6 +6002,7 @@ static const struct bpf_func_proto bpf_lua_pushmap_proto = {
59756002
};
59766003

59776004
BPF_CALL_3(bpf_lua_pushlstring, struct xdp_buff *, ctx, const char *, str, size_t, len) {
6005+
verify_and_lock();
59786006
lua_pushlstring(ctx->L, str, len);
59796007
return 0;
59806008
}
@@ -5990,6 +6018,7 @@ static const struct bpf_func_proto bpf_lua_pushlstring_proto = {
59906018
};
59916019

59926020
BPF_CALL_1(bpf_lua_pushskb, struct xdp_buff *, ctx) {
6021+
verify_and_lock();
59936022
lua_pushlightuserdata(ctx->L, ctx->skb);
59946023
return 0;
59956024
}
@@ -6003,6 +6032,7 @@ static const struct bpf_func_proto bpf_lua_pushskb_proto = {
60036032
};
60046033

60056034
BPF_CALL_2(bpf_lua_pushstring, struct xdp_buff *, ctx, const char *, str) {
6035+
verify_and_lock();
60066036
lua_pushstring(ctx->L, str);
60076037
return 0;
60086038
}
@@ -6016,28 +6046,8 @@ static const struct bpf_func_proto bpf_lua_pushstring_proto = {
60166046
.arg2_type = ARG_ANYTHING,
60176047
};
60186048

6019-
BPF_CALL_1(bpf_lua_setstate, struct xdp_buff *, ctx){
6020-
struct lua_state_cpu *sc;
6021-
int cpu = smp_processor_id();
6022-
6023-
list_for_each_entry(sc, &lua_state_cpu_list, list) {
6024-
if (sc->cpu == cpu) {
6025-
ctx->L = sc->L;
6026-
break;
6027-
}
6028-
}
6029-
return 0;
6030-
}
6031-
6032-
static const struct bpf_func_proto bpf_lua_setstate_proto = {
6033-
.func = bpf_lua_setstate,
6034-
.gpl_only = false,
6035-
.pkt_access = false,
6036-
.ret_type = RET_VOID,
6037-
.arg1_type = ARG_PTR_TO_CTX,
6038-
};
6039-
60406049
BPF_CALL_2(bpf_lua_toboolean, struct xdp_buff *, ctx, int, index) {
6050+
verify_and_lock();
60416051
return lua_toboolean(ctx->L, index);
60426052
}
60436053

@@ -6051,6 +6061,7 @@ static const struct bpf_func_proto bpf_lua_toboolean_proto = {
60516061
};
60526062

60536063
BPF_CALL_2(bpf_lua_tointeger, struct xdp_buff *, ctx, int, index) {
6064+
verify_and_lock();
60546065
return lua_tointeger(ctx->L, index);
60556066
}
60566067

@@ -6161,8 +6172,6 @@ bpf_base_func_proto(enum bpf_func_id func_id)
61616172
return &bpf_lua_pushskb_proto;
61626173
case BPF_FUNC_lua_pushstring:
61636174
return &bpf_lua_pushstring_proto;
6164-
case BPF_FUNC_lua_setstate:
6165-
return &bpf_lua_setstate_proto;
61666175
case BPF_FUNC_lua_toboolean:
61676176
return &bpf_lua_toboolean_proto;
61686177
case BPF_FUNC_lua_tointeger:

samples/bpf/xdplua_map_kern.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ int xdp_lua_test_map_prog(struct xdp_md *ctx)
2727
char lookupname[] = "lookup";
2828
char updatename[] = "update";
2929

30-
bpf_lua_setstate(ctx);
3130
bpf_lua_pushmap(ctx, &lua_test_map);
3231
bpf_lua_pcall(ctx, updatename, 1, 0);
3332

0 commit comments

Comments
 (0)