Page MenuHomeFreeBSD

Drop unneeded null tests from RB_REMOVE_COLOR
ClosedPublic

Authored by dougm on Jun 1 2020, 3:30 AM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Nov 12, 4:06 AM
Unknown Object (File)
Sat, Nov 2, 3:58 PM
Unknown Object (File)
Tue, Oct 29, 3:16 AM
Unknown Object (File)
Oct 13 2024, 7:48 AM
Unknown Object (File)
Sep 26 2024, 6:36 AM
Unknown Object (File)
Sep 26 2024, 2:03 AM
Unknown Object (File)
Sep 24 2024, 2:52 AM
Unknown Object (File)
Sep 21 2024, 6:05 AM
Subscribers

Details

Summary

Consider the lines:
if (!L && !R) {

S1;
continue;

}
if (!R)

S2;

You can infer that, in S2, L must be true. We can rewrite as:
if (!L && !R) {

S1;
continue;

}
if (L)

S2;

or even as
if (L)

S2;

else if (!R) {

S1;
continue;

}

and this change does that rewrite in two places in RB_REMOVE_COLOR, where L and R abbreviate "the left (right) child of tmp is red".

In each of the two versions of S2, there is a null test on oleft (oright) which is redundant because we know each to be red, and therefore not null. Those null tests are removed.

After each of the rewrites described so far, there is an assignment of black to a node, conditioned on that node being non-null. In one case, this node, or null, started the loop iteration as the child of a red node, and is necessarily black already. So only make the assignment in the other case, when the node is known to be red, and thus non-null.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

dougm requested review of this revision.Jun 1 2020, 3:30 AM
dougm created this revision.

An assignment to black can be dropped in one case, but not the other, so fix that.

I got this page fault with D25089.72507.diff:

0200601 08:22:21 all (147/714): seekdir.sh

Fatal trap 12: page fault while in kernel mode
cpuid = 3; apic id = 03
fault virtual address	= 0x0
fault code		= supervisor read data, page not present
instruction pointer	= 0x20:0xffffffff8253e17e
stack pointer	        = 0x28:0xfffffe00e683b7d0
frame pointer	        = 0x28:0xfffffe00e683b7d0
code segment		= base 0x0, limit 0xfffff, type 0x1b
			= DPL 0, pres 1, long 1, def32 0, gran 1
processor eflags	= interrupt enabled, resume, IOPL = 0
current process		= 67589 (seekdir)
trap number		= 12
panic: page fault
cpuid = 3
time = 1590992542
KDB: stack backtrace:
db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe00e683b480
vpanic() at vpanic+0x182/frame 0xfffffe00e683b4d0
panic() at panic+0x43/frame 0xfffffe00e683b530
trap_fatal() at trap_fatal+0x387/frame 0xfffffe00e683b590
trap_pfault() at trap_pfault+0x99/frame 0xfffffe00e683b5f0
trap() at trap+0x2a5/frame 0xfffffe00e683b700
calltrap() at calltrap+0x8/frame 0xfffffe00e683b700
--- trap 0xc, rip = 0xffffffff8253e17e, rsp = 0xfffffe00e683b7d0, rbp = 0xfffffe00e683b7d0 ---
tmpfs_dir_RB_REMOVE() at tmpfs_dir_RB_REMOVE+0x1ee/frame 0xfffffe00e683b7d0
tmpfs_dir_detach() at tmpfs_dir_detach+0x7a/frame 0xfffffe00e683b800
tmpfs_remove() at tmpfs_remove+0x107/frame 0xfffffe00e683b850
VOP_REMOVE_APV() at VOP_REMOVE_APV+0x79/frame 0xfffffe00e683b870
kern_funlinkat() at kern_funlinkat+0x298/frame 0xfffffe00e683bab0
sys_unlink() at sys_unlink+0x28/frame 0xfffffe00e683bad0
amd64_syscall() at amd64_syscall+0x159/frame 0xfffffe00e683bbf0
fast_syscall_common() at fast_syscall_common+0x101/frame 0xfffffe00e683bbf0
--- syscall (10, FreeBSD ELF64, sys_unlink), rip = 0x80041fd3a, rsp = 0x7fffffffe2c8, rbp = 0x7fffffffe6c0 ---

https://people.freebsd.org/~pho/stress/log/doug071.txt

dougm removed a reviewer: markj.

Discard the second part of the change and see if the first part is broken.

Uptime with D25089.72515.diff is three hours.

Change the null test back to a redness test, in a way to encourage the compiler to skip the test when possible.

cc  -O2 -pipe -fno-strict-aliasing  -g -nostdinc  -I. -I../../.. -I../../../contrib/ck/include -I../../../contrib/libfdt -D_KERNEL -DHAVE_KERNEL_OPTION_HEADERS -include opt_global.h -fno-common    -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer  -fdebug-prefix-map=./machine=/usr/src/sys/amd64/include -fdebug-prefix-map=./x86=/usr/src/sys/x86/include -mcmodel=kernel -mno-red-zone -mno-mmx -mno-sse -msoft-float  -fno-asynchronous-unwind-tables -ffreestanding -fwrapv -fstack-protector -gdwarf-2 -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wcast-qual -Wundef -Wno-pointer-sign -D__printf__=__freebsd_kprintf__ -Wmissing-include-dirs -fdiagnostics-show-option -Wno-unknown-pragmas -Wno-error-tautological-compare -Wno-error-empty-body -Wno-error-parentheses-equality -Wno-error-unused-function -Wno-error-pointer-sign -Wno-error-shift-negative-value -Wno-address-of-packed-member -Wno-format-zero-length   -mno-aes -mno-avx  -std=iso9899:1999 -c /usr/src/sys/vm/vm_phys.c -o /usr/src/sys/vm/vm_phys.o
/usr/src/sys/vm/vm_phys.c:103:1: error: called object type 'int' is not a function or function pointer
RB_GENERATE_STATIC(fict_tree, vm_phys_fictitious_seg, node,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../../sys/tree.h:424:2: note: expanded from macro 'RB_GENERATE_STATIC'
        RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static)
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../../sys/tree.h:427:2: note: expanded from macro 'RB_GENERATE_INTERNAL'
        RB_GENERATE_REMOVE_COLOR(name, type, field, attr)               \
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../../sys/tree.h:510:5: note: expanded from macro 'RB_GENERATE_REMOVE_COLOR'
                                RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK; \
                                ^
../../../sys/tree.h:323:31: note: expanded from macro 'RB_COLOR'
#define RB_COLOR(elm, field)            (elm)->field.rbe_color
                                        ^
/usr/src/sys/vm/vm_phys.c:103:1: error: too few arguments provided to function-like macro invocation
../../../sys/tree.h:424:2: note: expanded from macro 'RB_GENERATE_STATIC'
        RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static)
        ^
../../../sys/tree.h:427:2: note: expanded from macro 'RB_GENERATE_INTERNAL'
        RB_GENERATE_REMOVE_COLOR(name, type, field, attr)               \
        ^
../../../sys/tree.h:536:36: note: expanded from macro 'RB_GENERATE_REMOVE_COLOR'
                        if (RB_ISRED(RB_LEFT(tmp, field)))              \
                                                        ^
../../../sys/tree.h:324:9: note: macro 'RB_ISRED' defined here
#define RB_ISRED(elm, field)            ((elm) != NULL && RB_COLOR(elm, field) == RB_RED)
        ^
/usr/src/sys/vm/vm_phys.c:103:1: error: use of undeclared identifier 'RB_ISRED'
RB_GENERATE_STATIC(fict_tree, vm_phys_fictitious_seg, node,
^
../../../sys/tree.h:424:2: note: expanded from macro 'RB_GENERATE_STATIC'
        RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static)
        ^
../../../sys/tree.h:427:2: note: expanded from macro 'RB_GENERATE_INTERNAL'
        RB_GENERATE_REMOVE_COLOR(name, type, field, attr)               \
        ^
../../../sys/tree.h:536:8: note: expanded from macro 'RB_GENERATE_REMOVE_COLOR'
                        if (RB_ISRED(RB_LEFT(tmp, field)))              \
                            ^
3 errors generated.
*** Error code 1

I apologize for failing to test for successful compilation.

I apologize for failing to test for successful compilation.

No problem! Patch looks good so far; 40 minutes uptime.

I ran stress2 tests for 12 hours followed by a buildworld.
D25089.72543.diff LGTM.

This revision is now accepted and ready to land.Jun 2 2020, 3:46 PM