History

bpf: Add per-program recursion prevention mechanism

Since both sleepable and non-sleepable programs execute under migrate_disable add recursion prevention mechanism to both types of programs when they're executed via bpf trampoline.

Alexei Starovoitov committed 5 years ago

Commit ca06f551 parent f2dd3b37 files · +50 −11Browse files

Showing the changes to kernel (2 of 7 files). Show all

Unified · Split

2 files
  1. kernel/bpf/core.c +8 −0
  2. kernel/bpf/trampoline.c +19 −4
kernel/bpf/core.c+8−0
@@ -91,6 +91,12 @@ struct bpf_prog *bpf_prog_alloc_no_stats(unsigned int size, gfp_t gfp_extra_flag · 90 unmodified lines
9191 vfree(fp);
9292 return NULL;
9393 }
94+ fp->active = alloc_percpu_gfp(int, GFP_KERNEL_ACCOUNT | gfp_extra_flags);
95+ if (!fp->active) {
96+ vfree(fp);
97+ kfree(aux);
98+ return NULL;
99+ }
94100
95101 fp->pages = size / PAGE_SIZE;
96102 fp->aux = aux;
@@ -116,6 +122,7 @@ struct bpf_prog *bpf_prog_alloc(unsigned int size, gfp_t gfp_extra_flags) · 19 unmodified lines
116122
117123 prog->stats = alloc_percpu_gfp(struct bpf_prog_stats, gfp_flags);
118124 if (!prog->stats) {
125+ free_percpu(prog->active);
119126 kfree(prog->aux);
120127 vfree(prog);
121128 return NULL;
@@ -253,6 +260,7 @@ void __bpf_prog_free(struct bpf_prog *fp) · 131 unmodified lines
253260 kfree(fp->aux);
254261 }
255262 free_percpu(fp->stats);
263+ free_percpu(fp->active);
256264 vfree(fp);
257265 }
258266
kernel/bpf/trampoline.c+19−4
@@ -381,13 +381,16 @@ out: · 380 unmodified lines
381381 mutex_unlock(&trampoline_mutex);
382382 }
383383
384−#define NO_START_TIME 0
384+#define NO_START_TIME 1
385385 static u64 notrace bpf_prog_start_time(void)
386386 {
387387 u64 start = NO_START_TIME;
388388
389− if (static_branch_unlikely(&bpf_stats_enabled_key))
389+ if (static_branch_unlikely(&bpf_stats_enabled_key)) {
390390 start = sched_clock();
391+ if (unlikely(!start))
392+ start = NO_START_TIME;
393+ }
391394 return start;
392395 }
393396
@@ -397,12 +400,20 @@ static u64 notrace bpf_prog_start_time(void) · 3 unmodified lines
397400 * call __bpf_prog_enter
398401 * call prog->bpf_func
399402 * call __bpf_prog_exit
403+ *
404+ * __bpf_prog_enter returns:
405+ * 0 - skip execution of the bpf prog
406+ * 1 - execute bpf prog
407+ * [2..MAX_U64] - excute bpf prog and record execution time.
408+ * This is start time.
400409 */
401−u64 notrace __bpf_prog_enter(void)
410+u64 notrace __bpf_prog_enter(struct bpf_prog *prog)
402411 __acquires(RCU)
403412 {
404413 rcu_read_lock();
405414 migrate_disable();
415+ if (unlikely(__this_cpu_inc_return(*(prog->active)) != 1))
416+ return 0;
406417 return bpf_prog_start_time();
407418 }
408419
@@ -430,21 +441,25 @@ void notrace __bpf_prog_exit(struct bpf_prog *prog, u64 start) · 21 unmodified lines
430441 __releases(RCU)
431442 {
432443 update_prog_stats(prog, start);
444+ __this_cpu_dec(*(prog->active));
433445 migrate_enable();
434446 rcu_read_unlock();
435447 }
436448
437−u64 notrace __bpf_prog_enter_sleepable(void)
449+u64 notrace __bpf_prog_enter_sleepable(struct bpf_prog *prog)
438450 {
439451 rcu_read_lock_trace();
440452 migrate_disable();
441453 might_fault();
454+ if (unlikely(__this_cpu_inc_return(*(prog->active)) != 1))
455+ return 0;
442456 return bpf_prog_start_time();
443457 }
444458
445459 void notrace __bpf_prog_exit_sleepable(struct bpf_prog *prog, u64 start)
446460 {
447461 update_prog_stats(prog, start);
462+ __this_cpu_dec(*(prog->active));
448463 migrate_enable();
449464 rcu_read_unlock_trace();
450465 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t