Skip to content

Commit fc3fe38

Browse files
Fix script loading synchronization issue
1 parent 58abdd0 commit fc3fe38

8 files changed

Lines changed: 99 additions & 75 deletions

File tree

include/linux/filter.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,13 +1113,4 @@ struct bpf_sock_ops_kern {
11131113
*/
11141114
};
11151115

1116-
#ifdef CONFIG_XDP_LUA
1117-
extern struct list_head lua_state_cpu_list;
1118-
1119-
struct lua_state_cpu {
1120-
struct lua_State *L;
1121-
int cpu;
1122-
struct list_head list;
1123-
};
1124-
#endif /* CONFIG_XDP_LUA */
11251116
#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: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2238,9 +2238,10 @@ union bpf_attr {
22382238
FN(lua_pushmap), \
22392239
FN(lua_pushskb), \
22402240
FN(lua_pushstring), \
2241-
FN(lua_setstate), \
22422241
FN(lua_toboolean), \
2243-
FN(lua_tointeger),
2242+
FN(lua_tointeger), \
2243+
FN(lua_newpacket), \
2244+
FN(lua_type),
22442245
/* #endif CONFIG_XDP_LUA */
22452246

22462247
/* integer value in 'imm' field of BPF_CALL instruction selects which helper

net/core/dev.c

Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
#ifdef CONFIG_XDP_LUA
7676
#include <lua.h>
7777
#include <lauxlib.h>
78+
#include <lstate.h>
7879
#include <lualib.h>
7980
#include <luadata.h>
8081
#endif /* CONFIG_XDP_LUA */
@@ -162,6 +163,9 @@
162163

163164
static DEFINE_SPINLOCK(ptype_lock);
164165
static DEFINE_SPINLOCK(offload_lock);
166+
#ifdef CONFIG_XDP_LUA
167+
DEFINE_PER_CPU(struct xdplua_create_work, luaworks);
168+
#endif
165169
struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly;
166170
struct list_head ptype_all __read_mostly; /* Taps */
167171
static struct list_head offload_base __read_mostly;
@@ -171,10 +175,6 @@ static int call_netdevice_notifiers_info(unsigned long val,
171175
struct netdev_notifier_info *info);
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.
@@ -4290,6 +4290,9 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,
42904290
u32 metalen, act = XDP_DROP;
42914291
int hlen, off;
42924292
u32 mac_len;
4293+
#ifdef CONFIG_XDP_LUA
4294+
struct xdplua_create_work *lw;
4295+
#endif /* CONFIG_XDP_LUA */
42934296

42944297
/* Reinjected packets coming from act_mirred or similar should
42954298
* not get XDP generic processing.
@@ -4332,11 +4335,21 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,
43324335
rxqueue = netif_get_rxqueue(skb);
43334336
xdp->rxq = &rxqueue->xdp_rxq;
43344337
#ifdef CONFIG_XDP_LUA
4338+
lw = this_cpu_ptr(&luaworks);
4339+
43354340
xdp->skb = skb;
4341+
xdp->L = lw->L;
43364342
#endif /* CONFIG_XDP_LUA */
43374343

43384344
act = bpf_prog_run_xdp(xdp_prog, xdp);
43394345

4346+
#ifdef CONFIG_XDP_LUA
4347+
if (lw->init) {
4348+
lw->init = false;
4349+
spin_unlock(&lw->lock);
4350+
}
4351+
#endif /* CONFIG_XDP_LUA */
4352+
43404353
off = xdp->data - orig_data;
43414354
if (off > 0)
43424355
__skb_pull(skb, off);
@@ -5103,16 +5116,29 @@ static int generic_xdp_install(struct net_device *dev, struct netdev_bpf *xdp)
51035116
}
51045117

51055118
#ifdef CONFIG_XDP_LUA
5106-
int generic_xdp_lua_install_prog(char *lua_prog)
5119+
5120+
static void per_cpu_xdp_lua_install(struct work_struct *w) {
5121+
int this_cpu = smp_processor_id();
5122+
struct xdplua_create_work *lw =
5123+
container_of(w, struct xdplua_create_work, work);
5124+
5125+
spin_lock_bh(&lw->lock);
5126+
if (luaL_dostring(lw->L, lw->lua_script)) {
5127+
pr_err(KERN_INFO "error: %s\nOn cpu: %d\n",
5128+
lua_tostring(lw->L, -1), this_cpu);
5129+
}
5130+
spin_unlock_bh(&lw->lock);
5131+
}
5132+
5133+
int generic_xdp_lua_install_prog(char *lua_script)
51075134
{
5108-
struct lua_state_cpu *sc;
5135+
int cpu;
5136+
struct xdplua_create_work *lw;
51095137

5110-
list_for_each_entry(sc, &lua_state_cpu_list, list) {
5111-
if (luaL_dostring(sc->L, lua_prog)) {
5112-
pr_err(KERN_INFO "error: %s\nOn cpu: %d\n",
5113-
lua_tostring(sc->L, -1), sc->cpu);
5114-
return -EINVAL;
5115-
}
5138+
for_each_possible_cpu(cpu) {
5139+
lw = per_cpu_ptr(&luaworks, cpu);
5140+
strcpy(lw->lua_script, lua_script);
5141+
schedule_work_on(cpu, &lw->work);
51165142
}
51175143
return 0;
51185144
}
@@ -9600,9 +9626,6 @@ static struct pernet_operations __net_initdata default_device_ops = {
96009626
static int __init net_dev_init(void)
96019627
{
96029628
int i, rc = -ENOMEM;
9603-
#ifdef CONFIG_XDP_LUA
9604-
struct lua_state_cpu *new_state_cpu;
9605-
#endif /* CONFIG_XDP_LUA */
96069629

96079630
BUG_ON(!dev_boot_phase);
96089631

@@ -9617,9 +9640,6 @@ static int __init net_dev_init(void)
96179640
INIT_LIST_HEAD(&ptype_base[i]);
96189641

96199642
INIT_LIST_HEAD(&offload_base);
9620-
#ifdef CONFIG_XDP_LUA
9621-
INIT_LIST_HEAD(&lua_state_cpu_list);
9622-
#endif /* CONFIG_XDP_LUA */
96239643

96249644
if (register_pernet_subsys(&netdev_net_ops))
96259645
goto out;
@@ -9631,6 +9651,9 @@ static int __init net_dev_init(void)
96319651
for_each_possible_cpu(i) {
96329652
struct work_struct *flush = per_cpu_ptr(&flush_works, i);
96339653
struct softnet_data *sd = &per_cpu(softnet_data, i);
9654+
#ifdef CONFIG_XDP_LUA
9655+
struct xdplua_create_work *lw = per_cpu_ptr(&luaworks, i);
9656+
#endif
96349657

96359658
INIT_WORK(flush, flush_backlog);
96369659

@@ -9650,24 +9673,18 @@ static int __init net_dev_init(void)
96509673
init_gro_hash(&sd->backlog);
96519674
sd->backlog.poll = process_backlog;
96529675
sd->backlog.weight = weight_p;
9653-
96549676
#ifdef CONFIG_XDP_LUA
9655-
new_state_cpu = (struct lua_state_cpu *)
9656-
kmalloc(sizeof(struct lua_state_cpu), GFP_ATOMIC);
9657-
if (!new_state_cpu)
9658-
continue;
9677+
lw->L = luaL_newstate();
9678+
WARN_ON(!lw->L);
96599679

9660-
new_state_cpu->L = luaL_newstate();
9661-
if (!new_state_cpu->L) {
9662-
kfree(new_state_cpu);
9680+
if (!lw->L)
96639681
continue;
9664-
}
96659682

9666-
luaL_openlibs(new_state_cpu->L);
9667-
lua_pop(new_state_cpu->L, 1);
9668-
new_state_cpu->cpu = i;
9683+
luaL_openlibs(lw->L);
9684+
luaL_requiref(lw->L, "data", luaopen_data, 1);
9685+
lua_pop(lw->L, 1);
96699686

9670-
list_add(&new_state_cpu->list, &lua_state_cpu_list);
9687+
INIT_WORK(&lw->work, per_cpu_xdp_lua_install);
96719688
#endif /* CONFIG_XDP_LUA */
96729689
}
96739690

net/core/filter.c

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4792,10 +4792,21 @@ static const struct bpf_func_proto bpf_lwt_seg6_adjust_srh_proto = {
47924792
#endif /* CONFIG_IPV6_SEG6_BPF */
47934793

47944794
#ifdef CONFIG_XDP_LUA
4795+
static inline void verify_and_lock(void) {
4796+
struct xdplua_create_work *lw;
4797+
4798+
lw = this_cpu_ptr(&luaworks);
4799+
if (!lw->init) {
4800+
lw->init = true;
4801+
spin_lock(&lw->lock);
4802+
}
4803+
}
4804+
47954805
BPF_CALL_2(bpf_lua_dataref, struct xdp_buff *, ctx, int, offset) {
47964806
if (offset + ctx->data < ctx->data_end) {
47974807
int data_ref;
47984808

4809+
verify_and_lock();
47994810
data_ref = ldata_newref(ctx->L, ctx->data + offset,
48004811
ctx->data_end - ctx->data - offset);
48014812
return data_ref;
@@ -4814,6 +4825,7 @@ static const struct bpf_func_proto bpf_lua_dataref_proto = {
48144825
};
48154826

48164827
BPF_CALL_2(bpf_lua_dataunref, struct xdp_buff *, ctx, int, data_ref) {
4828+
verify_and_lock();
48174829
ldata_unref(ctx->L, data_ref);
48184830
return 0;
48194831
}
@@ -4828,19 +4840,28 @@ static const struct bpf_func_proto bpf_lua_dataunref_proto = {
48284840
};
48294841

48304842
BPF_CALL_4(bpf_lua_pcall, struct xdp_buff *, ctx, char *, funcname,
4831-
int, num_args, int, num_rets) {
4843+
int, num_args, int, num_rets) {
4844+
int base;
4845+
4846+
verify_and_lock();
4847+
4848+
base = lua_gettop(ctx->L) - num_args;
48324849
if (lua_getglobal(ctx->L, funcname) != LUA_TFUNCTION) {
48334850
pr_err("function %s not found\n", funcname);
4834-
lua_pop(ctx->L, num_args);
4835-
return 0;
4851+
num_rets = 0;
4852+
goto clean_state;
48364853
}
48374854

48384855
lua_insert(ctx->L, 1);
48394856
if (lua_pcall(ctx->L, num_args, num_rets, 0)) {
48404857
pr_err("%s\n", lua_tostring(ctx->L, -1));
4841-
lua_pop(ctx->L, 1);
4842-
return 0;
4858+
num_rets = 0;
4859+
goto clean_state;
48434860
}
4861+
4862+
clean_state:
4863+
base += num_rets;
4864+
lua_settop(ctx->L, base);
48444865
return num_rets;
48454866
}
48464867

@@ -4856,6 +4877,7 @@ static const struct bpf_func_proto bpf_lua_pcall_proto = {
48564877
};
48574878

48584879
BPF_CALL_2(bpf_lua_pop, struct xdp_buff *, ctx, int, index) {
4880+
verify_and_lock();
48594881
lua_pop(ctx->L, index);
48604882
return 0;
48614883
}
@@ -4870,6 +4892,7 @@ static const struct bpf_func_proto bpf_lua_pop_proto = {
48704892
};
48714893

48724894
BPF_CALL_2(bpf_lua_pushinteger, struct xdp_buff *, ctx, int, num) {
4895+
verify_and_lock();
48734896
lua_pushinteger(ctx->L, num);
48744897
return 0;
48754898
}
@@ -4884,6 +4907,7 @@ static const struct bpf_func_proto bpf_lua_pushinteger_proto = {
48844907
};
48854908

48864909
BPF_CALL_2(bpf_lua_pushlightuserdata, struct xdp_buff *, ctx, void *, ptr) {
4910+
verify_and_lock();
48874911
lua_pushlightuserdata(ctx->L, ptr);
48884912
return 0;
48894913
}
@@ -4898,6 +4922,7 @@ static const struct bpf_func_proto bpf_lua_pushlightuserdata_proto = {
48984922
};
48994923

49004924
BPF_CALL_3(bpf_lua_pushlstring, struct xdp_buff *, ctx, const char *, str, size_t, len) {
4925+
verify_and_lock();
49014926
lua_pushlstring(ctx->L, str, len);
49024927
return 0;
49034928
}
@@ -4913,6 +4938,7 @@ static const struct bpf_func_proto bpf_lua_pushlstring_proto = {
49134938
};
49144939

49154940
BPF_CALL_2(bpf_lua_pushmap, struct xdp_buff *, ctx, struct bpf_map *, map) {
4941+
verify_and_lock();
49164942
lua_pushlightuserdata(ctx->L, map);
49174943
return 0;
49184944
}
@@ -4927,6 +4953,7 @@ static const struct bpf_func_proto bpf_lua_pushmap_proto = {
49274953
};
49284954

49294955
BPF_CALL_1(bpf_lua_pushskb, struct xdp_buff *, ctx) {
4956+
verify_and_lock();
49304957
lua_pushlightuserdata(ctx->L, ctx->skb);
49314958
return 0;
49324959
}
@@ -4940,6 +4967,7 @@ static const struct bpf_func_proto bpf_lua_pushskb_proto = {
49404967
};
49414968

49424969
BPF_CALL_2(bpf_lua_pushstring, struct xdp_buff *, ctx, const char *, str) {
4970+
verify_and_lock();
49434971
lua_pushstring(ctx->L, str);
49444972
return 0;
49454973
}
@@ -4953,28 +4981,8 @@ static const struct bpf_func_proto bpf_lua_pushstring_proto = {
49534981
.arg2_type = ARG_ANYTHING,
49544982
};
49554983

4956-
BPF_CALL_1(bpf_lua_setstate, struct xdp_buff *, ctx){
4957-
struct lua_state_cpu *sc;
4958-
int cpu = smp_processor_id();
4959-
4960-
list_for_each_entry(sc, &lua_state_cpu_list, list) {
4961-
if (sc->cpu == cpu) {
4962-
ctx->L = sc->L;
4963-
break;
4964-
}
4965-
}
4966-
return 0;
4967-
}
4968-
4969-
static const struct bpf_func_proto bpf_lua_setstate_proto = {
4970-
.func = bpf_lua_setstate,
4971-
.gpl_only = false,
4972-
.pkt_access = false,
4973-
.ret_type = RET_VOID,
4974-
.arg1_type = ARG_PTR_TO_CTX,
4975-
};
4976-
49774984
BPF_CALL_2(bpf_lua_toboolean, struct xdp_buff *, ctx, int, index) {
4985+
verify_and_lock();
49784986
return lua_toboolean(ctx->L, index);
49794987
}
49804988

@@ -4988,6 +4996,7 @@ static const struct bpf_func_proto bpf_lua_toboolean_proto = {
49884996
};
49894997

49904998
BPF_CALL_2(bpf_lua_tointeger, struct xdp_buff *, ctx, int, index) {
4999+
verify_and_lock();
49915000
return lua_tointeger(ctx->L, index);
49925001
}
49935002

@@ -5077,8 +5086,6 @@ bpf_base_func_proto(enum bpf_func_id func_id)
50775086
return &bpf_lua_pushskb_proto;
50785087
case BPF_FUNC_lua_pushstring:
50795088
return &bpf_lua_pushstring_proto;
5080-
case BPF_FUNC_lua_setstate:
5081-
return &bpf_lua_setstate_proto;
50825089
case BPF_FUNC_lua_toboolean:
50835090
return &bpf_lua_toboolean_proto;
50845091
case BPF_FUNC_lua_tointeger:

samples/bpf/xdplua_map_kern.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +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);
31-
3230
bpf_lua_pushmap(ctx, &test_map);
3331
bpf_lua_pcall(ctx, updatename, 1, 0);
3432

tools/include/uapi/linux/bpf.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2238,7 +2238,6 @@ union bpf_attr {
22382238
FN(lua_pushmap), \
22392239
FN(lua_pushskb), \
22402240
FN(lua_pushstring), \
2241-
FN(lua_setstate), \
22422241
FN(lua_toboolean), \
22432242
FN(lua_tointeger),
22442243
/* #endif CONFIG_XDP_LUA */

0 commit comments

Comments
 (0)