diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Kconfig.debug | 33 | ||||
| -rw-r--r-- | lib/rbtree.c | 10 | ||||
| -rw-r--r-- | lib/test_bpf.c | 43 |
3 files changed, 53 insertions, 33 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 947d3e2ed5c2..9d5b78aad4c5 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
| @@ -1099,8 +1099,6 @@ config PROVE_LOCKING | |||
| 1099 | select DEBUG_MUTEXES | 1099 | select DEBUG_MUTEXES |
| 1100 | select DEBUG_RT_MUTEXES if RT_MUTEXES | 1100 | select DEBUG_RT_MUTEXES if RT_MUTEXES |
| 1101 | select DEBUG_LOCK_ALLOC | 1101 | select DEBUG_LOCK_ALLOC |
| 1102 | select LOCKDEP_CROSSRELEASE | ||
| 1103 | select LOCKDEP_COMPLETIONS | ||
| 1104 | select TRACE_IRQFLAGS | 1102 | select TRACE_IRQFLAGS |
| 1105 | default n | 1103 | default n |
| 1106 | help | 1104 | help |
| @@ -1170,37 +1168,6 @@ config LOCK_STAT | |||
| 1170 | CONFIG_LOCK_STAT defines "contended" and "acquired" lock events. | 1168 | CONFIG_LOCK_STAT defines "contended" and "acquired" lock events. |
| 1171 | (CONFIG_LOCKDEP defines "acquire" and "release" events.) | 1169 | (CONFIG_LOCKDEP defines "acquire" and "release" events.) |
| 1172 | 1170 | ||
| 1173 | config LOCKDEP_CROSSRELEASE | ||
| 1174 | bool | ||
| 1175 | help | ||
| 1176 | This makes lockdep work for crosslock which is a lock allowed to | ||
| 1177 | be released in a different context from the acquisition context. | ||
| 1178 | Normally a lock must be released in the context acquiring the lock. | ||
| 1179 | However, relexing this constraint helps synchronization primitives | ||
| 1180 | such as page locks or completions can use the lock correctness | ||
| 1181 | detector, lockdep. | ||
| 1182 | |||
| 1183 | config LOCKDEP_COMPLETIONS | ||
| 1184 | bool | ||
| 1185 | help | ||
| 1186 | A deadlock caused by wait_for_completion() and complete() can be | ||
| 1187 | detected by lockdep using crossrelease feature. | ||
| 1188 | |||
| 1189 | config BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK | ||
| 1190 | bool "Enable the boot parameter, crossrelease_fullstack" | ||
| 1191 | depends on LOCKDEP_CROSSRELEASE | ||
| 1192 | default n | ||
| 1193 | help | ||
| 1194 | The lockdep "cross-release" feature needs to record stack traces | ||
| 1195 | (of calling functions) for all acquisitions, for eventual later | ||
| 1196 | use during analysis. By default only a single caller is recorded, | ||
| 1197 | because the unwind operation can be very expensive with deeper | ||
| 1198 | stack chains. | ||
| 1199 | |||
| 1200 | However a boot parameter, crossrelease_fullstack, was | ||
| 1201 | introduced since sometimes deeper traces are required for full | ||
| 1202 | analysis. This option turns on the boot parameter. | ||
| 1203 | |||
| 1204 | config DEBUG_LOCKDEP | 1171 | config DEBUG_LOCKDEP |
| 1205 | bool "Lock dependency engine debugging" | 1172 | bool "Lock dependency engine debugging" |
| 1206 | depends on DEBUG_KERNEL && LOCKDEP | 1173 | depends on DEBUG_KERNEL && LOCKDEP |
diff --git a/lib/rbtree.c b/lib/rbtree.c index ba4a9d165f1b..d3ff682fd4b8 100644 --- a/lib/rbtree.c +++ b/lib/rbtree.c | |||
| @@ -603,6 +603,16 @@ void rb_replace_node(struct rb_node *victim, struct rb_node *new, | |||
| 603 | } | 603 | } |
| 604 | EXPORT_SYMBOL(rb_replace_node); | 604 | EXPORT_SYMBOL(rb_replace_node); |
| 605 | 605 | ||
| 606 | void rb_replace_node_cached(struct rb_node *victim, struct rb_node *new, | ||
| 607 | struct rb_root_cached *root) | ||
| 608 | { | ||
| 609 | rb_replace_node(victim, new, &root->rb_root); | ||
| 610 | |||
| 611 | if (root->rb_leftmost == victim) | ||
| 612 | root->rb_leftmost = new; | ||
| 613 | } | ||
| 614 | EXPORT_SYMBOL(rb_replace_node_cached); | ||
| 615 | |||
| 606 | void rb_replace_node_rcu(struct rb_node *victim, struct rb_node *new, | 616 | void rb_replace_node_rcu(struct rb_node *victim, struct rb_node *new, |
| 607 | struct rb_root *root) | 617 | struct rb_root *root) |
| 608 | { | 618 | { |
diff --git a/lib/test_bpf.c b/lib/test_bpf.c index aa8812ae6776..9e9748089270 100644 --- a/lib/test_bpf.c +++ b/lib/test_bpf.c | |||
| @@ -435,6 +435,41 @@ loop: | |||
| 435 | return 0; | 435 | return 0; |
| 436 | } | 436 | } |
| 437 | 437 | ||
| 438 | static int bpf_fill_ld_abs_vlan_push_pop2(struct bpf_test *self) | ||
| 439 | { | ||
| 440 | struct bpf_insn *insn; | ||
| 441 | |||
| 442 | insn = kmalloc_array(16, sizeof(*insn), GFP_KERNEL); | ||
| 443 | if (!insn) | ||
| 444 | return -ENOMEM; | ||
| 445 | |||
| 446 | /* Due to func address being non-const, we need to | ||
| 447 | * assemble this here. | ||
| 448 | */ | ||
| 449 | insn[0] = BPF_MOV64_REG(R6, R1); | ||
| 450 | insn[1] = BPF_LD_ABS(BPF_B, 0); | ||
| 451 | insn[2] = BPF_LD_ABS(BPF_H, 0); | ||
| 452 | insn[3] = BPF_LD_ABS(BPF_W, 0); | ||
| 453 | insn[4] = BPF_MOV64_REG(R7, R6); | ||
| 454 | insn[5] = BPF_MOV64_IMM(R6, 0); | ||
| 455 | insn[6] = BPF_MOV64_REG(R1, R7); | ||
| 456 | insn[7] = BPF_MOV64_IMM(R2, 1); | ||
| 457 | insn[8] = BPF_MOV64_IMM(R3, 2); | ||
| 458 | insn[9] = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
| 459 | bpf_skb_vlan_push_proto.func - __bpf_call_base); | ||
| 460 | insn[10] = BPF_MOV64_REG(R6, R7); | ||
| 461 | insn[11] = BPF_LD_ABS(BPF_B, 0); | ||
| 462 | insn[12] = BPF_LD_ABS(BPF_H, 0); | ||
| 463 | insn[13] = BPF_LD_ABS(BPF_W, 0); | ||
| 464 | insn[14] = BPF_MOV64_IMM(R0, 42); | ||
| 465 | insn[15] = BPF_EXIT_INSN(); | ||
| 466 | |||
| 467 | self->u.ptr.insns = insn; | ||
| 468 | self->u.ptr.len = 16; | ||
| 469 | |||
| 470 | return 0; | ||
| 471 | } | ||
| 472 | |||
| 438 | static int bpf_fill_jump_around_ld_abs(struct bpf_test *self) | 473 | static int bpf_fill_jump_around_ld_abs(struct bpf_test *self) |
| 439 | { | 474 | { |
| 440 | unsigned int len = BPF_MAXINSNS; | 475 | unsigned int len = BPF_MAXINSNS; |
| @@ -6066,6 +6101,14 @@ static struct bpf_test tests[] = { | |||
| 6066 | {}, | 6101 | {}, |
| 6067 | { {0x1, 0x42 } }, | 6102 | { {0x1, 0x42 } }, |
| 6068 | }, | 6103 | }, |
| 6104 | { | ||
| 6105 | "LD_ABS with helper changing skb data", | ||
| 6106 | { }, | ||
| 6107 | INTERNAL, | ||
| 6108 | { 0x34 }, | ||
| 6109 | { { ETH_HLEN, 42 } }, | ||
| 6110 | .fill_helper = bpf_fill_ld_abs_vlan_push_pop2, | ||
| 6111 | }, | ||
| 6069 | }; | 6112 | }; |
| 6070 | 6113 | ||
| 6071 | static struct net_device dev; | 6114 | static struct net_device dev; |
